mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 22:33:08 +00:00
Compare commits
146 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03a147ea0 | ||
|
|
7218218040 | ||
|
|
f377ea1060 | ||
|
|
455ea58872 | ||
|
|
925cc08b95 | ||
|
|
90e8af98eb | ||
|
|
16b331f5fd | ||
|
|
4bf17f0a78 | ||
|
|
59f92bff69 | ||
|
|
199782edd1 | ||
|
|
bf21e4f725 | ||
|
|
c4237e8909 | ||
|
|
0cb9ffc6d8 | ||
|
|
9070607c03 | ||
|
|
7199cfc21f | ||
|
|
b1082a31a5 | ||
|
|
55acb29d68 | ||
|
|
b21fa8e2cd | ||
|
|
5cfd47660c | ||
|
|
0934823815 | ||
|
|
e739ba1bd9 | ||
|
|
f592674642 | ||
|
|
566e4ab6b1 | ||
|
|
7b45bd3c09 | ||
|
|
e07d8fccd1 | ||
|
|
db936b9094 | ||
|
|
87983e800a | ||
|
|
142a890c37 | ||
|
|
331bd83f11 | ||
|
|
0209c68fcc | ||
|
|
aea1272a3f | ||
|
|
a09c1d91ed | ||
|
|
47e46b58d2 | ||
|
|
200fb1e92e | ||
|
|
8717453208 | ||
|
|
8a5f834240 | ||
|
|
bee19572c8 | ||
|
|
b5c22777f8 | ||
|
|
7e68999f79 | ||
|
|
470dac8a77 | ||
|
|
e6a71e9e7a | ||
|
|
168981c678 | ||
|
|
23ab05f1f5 | ||
|
|
160f2dabed | ||
|
|
53f298cffa | ||
|
|
3ca0f18bfe | ||
|
|
a8844ab3bc | ||
|
|
aa013b7643 | ||
|
|
f38a28a626 | ||
|
|
af6670c403 | ||
|
|
fd7aafdbd5 | ||
|
|
4b47e978e3 | ||
|
|
d80cfa6f41 | ||
|
|
379f1c9fa0 | ||
|
|
c0378e85b6 | ||
|
|
ebb37e719d | ||
|
|
527df938e1 | ||
|
|
1d34616236 | ||
|
|
a5f4107d3e | ||
|
|
2a7683933a | ||
|
|
83e1ce1e00 | ||
|
|
9397dc5af6 | ||
|
|
4ab34b142e | ||
|
|
fbb297fd2a | ||
|
|
8bb7c85bd4 | ||
|
|
79e3c4a9a8 | ||
|
|
60922dbf34 | ||
|
|
b2feb0d575 | ||
|
|
a100419d06 | ||
|
|
cf6c8eacfe | ||
|
|
cac0f56c03 | ||
|
|
a2ea4b02bc | ||
|
|
dac350f7c8 | ||
|
|
1bada4b275 | ||
|
|
f5de2770e5 | ||
|
|
d128f5c0bb | ||
|
|
06fc600aec | ||
|
|
0b4176891c | ||
|
|
ceb84c647b | ||
|
|
4089134892 | ||
|
|
f2c838d2cf | ||
|
|
edaa9584cc | ||
|
|
f5e7850686 | ||
|
|
6ecd143212 | ||
|
|
373ae980c0 | ||
|
|
b8d7866193 | ||
|
|
4c0913ff7c | ||
|
|
e5ea175ffb | ||
|
|
aca8ed9dec | ||
|
|
6ac462b088 | ||
|
|
9025f73733 | ||
|
|
1423b38c45 | ||
|
|
ed6418544c | ||
|
|
3ae9a99f62 | ||
|
|
8088105b05 | ||
|
|
38a8fd5d85 | ||
|
|
3592868435 | ||
|
|
27ae10afe0 | ||
|
|
f391a2cd20 | ||
|
|
172dc6c314 | ||
|
|
0d65b014ea | ||
|
|
27f3e8b61d | ||
|
|
9c857bb32d | ||
|
|
38ececf0a7 | ||
|
|
cb3eec285f | ||
|
|
598413357d | ||
|
|
0367d46d3c | ||
|
|
d67bf8bde3 | ||
|
|
7d8a556ba9 | ||
|
|
1aca3dd6e0 | ||
|
|
f062ec2a1a | ||
|
|
a7cfc23e5a | ||
|
|
e62a3ea74e | ||
|
|
eedfce92b0 | ||
|
|
7b9e482ed6 | ||
|
|
7757302c3a | ||
|
|
4f47be5c6b | ||
|
|
7199a86b97 | ||
|
|
fe8bdf6f04 | ||
|
|
c71b78eb01 | ||
|
|
59bdd77229 | ||
|
|
bfc554b542 | ||
|
|
fbdf64a7da | ||
|
|
74a79da4ec | ||
|
|
18b821666e | ||
|
|
6c690a966a | ||
|
|
f954950485 | ||
|
|
f79dacbfc4 | ||
|
|
dc75a64c46 | ||
|
|
fdc9326868 | ||
|
|
af4b39395c | ||
|
|
99b5a4f294 | ||
|
|
22b7d02282 | ||
|
|
623d5cc7f6 | ||
|
|
ba97b1a2a2 | ||
|
|
72775adcd0 | ||
|
|
372d56371f | ||
|
|
6d44a8cd0b | ||
|
|
71e2f653cf | ||
|
|
2ef72f84ca | ||
|
|
8b9c517515 | ||
|
|
1a7ffe4aae | ||
|
|
c9c58ebbe3 | ||
|
|
ed583e5466 | ||
|
|
8e91862571 | ||
|
|
61a95ab662 |
@ -1,13 +0,0 @@
|
||||
contact_links:
|
||||
- name: Language Proposal
|
||||
about: "Please do not submit a proposal to change the language"
|
||||
url: https://ziglang.org/code-of-conduct
|
||||
- name: Question
|
||||
about: "Please use one of the community spaces instead for questions or general discussions."
|
||||
url: https://ziglang.org/community
|
||||
- name: C Translation
|
||||
about: "Issues related to `zig translate-c` and `@cImport` are tracked separately."
|
||||
url: https://codeberg.org/ziglang/translate-c
|
||||
- name: Copilot and Other LLMs
|
||||
about: "Please do not use GitHub Copilot or any other LLM to write an issue."
|
||||
url: https://ziglang.org/code-of-conduct
|
||||
@ -1,196 +0,0 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.head_ref || github.run_id }}-${{ github.actor }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
aarch64-linux-debug:
|
||||
runs-on: [self-hosted, aarch64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-linux-debug.sh
|
||||
timeout-minutes: 180
|
||||
aarch64-linux-release:
|
||||
runs-on: [self-hosted, aarch64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-linux-release.sh
|
||||
timeout-minutes: 120
|
||||
|
||||
aarch64-macos-debug:
|
||||
runs-on: [self-hosted, aarch64-macos]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-macos-debug.sh
|
||||
timeout-minutes: 180
|
||||
aarch64-macos-release:
|
||||
runs-on: [self-hosted, aarch64-macos]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-macos-release.sh
|
||||
timeout-minutes: 120
|
||||
|
||||
loongarch64-linux-debug:
|
||||
runs-on: [self-hosted, loongarch64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/loongarch64-linux-debug.sh
|
||||
timeout-minutes: 240
|
||||
loongarch64-linux-release:
|
||||
runs-on: [self-hosted, loongarch64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/loongarch64-linux-release.sh
|
||||
timeout-minutes: 180
|
||||
|
||||
riscv64-linux-debug:
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: [self-hosted, riscv64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/riscv64-linux-debug.sh
|
||||
timeout-minutes: 600
|
||||
riscv64-linux-release:
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: [self-hosted, riscv64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/riscv64-linux-release.sh
|
||||
timeout-minutes: 480
|
||||
|
||||
s390x-linux-debug:
|
||||
runs-on: [self-hosted, s390x-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/s390x-linux-debug.sh
|
||||
timeout-minutes: 300
|
||||
s390x-linux-release:
|
||||
runs-on: [self-hosted, s390x-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/s390x-linux-release.sh
|
||||
timeout-minutes: 240
|
||||
|
||||
x86_64-freebsd-debug:
|
||||
runs-on: [self-hosted, x86_64-freebsd]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-freebsd-debug.sh
|
||||
timeout-minutes: 120
|
||||
x86_64-freebsd-release:
|
||||
runs-on: [self-hosted, x86_64-freebsd]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-freebsd-release.sh
|
||||
timeout-minutes: 120
|
||||
|
||||
x86_64-linux-debug:
|
||||
runs-on: [self-hosted, x86_64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-linux-debug.sh
|
||||
timeout-minutes: 240
|
||||
x86_64-linux-debug-llvm:
|
||||
runs-on: [self-hosted, x86_64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-linux-debug-llvm.sh
|
||||
timeout-minutes: 480
|
||||
x86_64-linux-release:
|
||||
runs-on: [self-hosted, x86_64-linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-linux-release.sh
|
||||
timeout-minutes: 480
|
||||
|
||||
x86_64-windows-debug:
|
||||
runs-on: [self-hosted, x86_64-windows]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: ci/x86_64-windows-debug.ps1
|
||||
timeout-minutes: 180
|
||||
x86_64-windows-release:
|
||||
runs-on: [self-hosted, x86_64-windows]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build and Test
|
||||
run: ci/x86_64-windows-release.ps1
|
||||
timeout-minutes: 180
|
||||
16
.gitattributes
vendored
16
.gitattributes
vendored
@ -2,24 +2,14 @@
|
||||
*.zon text eol=lf
|
||||
*.txt text eol=lf
|
||||
langref.html.in text eol=lf
|
||||
|
||||
lib/libc/*/abilists binary
|
||||
|
||||
lib/std/compress/testdata/** binary
|
||||
lib/std/compress/deflate/testdata/** binary
|
||||
lib/std/compress/flate/testdata/** binary
|
||||
lib/std/compress/lzma/testdata/** binary
|
||||
lib/std/compress/xz/testdata/** binary
|
||||
lib/std/crypto/codecs/asn1/der/testdata/** binary
|
||||
lib/std/tar/testdata/** binary
|
||||
src/Package/Fetch/testdata/** binary
|
||||
src/Package/Fetch/git/testdata/** binary
|
||||
|
||||
lib/compiler/aro/** linguist-vendored
|
||||
lib/compiler/resinator/** linguist-vendored
|
||||
lib/compiler/translate-c/** linguist-vendored
|
||||
lib/include/** linguist-vendored
|
||||
lib/libc/** linguist-vendored
|
||||
lib/libcxx/** linguist-vendored
|
||||
lib/libcxxabi/** linguist-vendored
|
||||
lib/libtsan/** linguist-vendored
|
||||
lib/libunwind/** linguist-vendored
|
||||
lib/tsan/** linguist-vendored
|
||||
lib/compiler/aro/** linguist-vendored
|
||||
|
||||
75
.github/CODE_OF_CONDUCT.md
vendored
Normal file
75
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
# Code of Conduct
|
||||
|
||||
Hello, and welcome! 👋
|
||||
|
||||
The Zig community is decentralized. Anyone is free to start and maintain their
|
||||
own space for people to gather, and edit
|
||||
[the Community wiki page](https://github.com/ziglang/zig/wiki/Community) to add
|
||||
a link. There is no concept of "official" or "unofficial", however, each
|
||||
gathering place has its own moderators and rules.
|
||||
|
||||
This is Andrew Kelley speaking. At least for now, I'm the moderator of the
|
||||
ziglang organization GitHub repositories and the #zig IRC channel on Libera.chat.
|
||||
**This document contains the rules that govern these two spaces only**.
|
||||
|
||||
The rules here are strict. This space is for focused, on topic, technical work
|
||||
on the Zig project only. It is everyone's responsibility to maintain a positive
|
||||
environment, especially when disagreements occur.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contribute to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language.
|
||||
* Being respectful of differing viewpoints and experiences.
|
||||
* Gracefully accepting constructive criticism.
|
||||
* Helping another person accomplish their own goals.
|
||||
* Showing empathy towards others.
|
||||
* Showing appreciation for others' work.
|
||||
* Validating someone else's experience, skills, insight, and use cases.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* Unwelcome sexual attention or advances, or use of sexualized language or
|
||||
imagery that causes discomfort.
|
||||
* Trolling, insulting/derogatory comments, and personal attacks. Anything
|
||||
antagonistic towards someone else.
|
||||
* Off-topic discussion of any kind - especially offensive or sensitive issues.
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission.
|
||||
* Discussing this Code of Conduct or publicly accusing someone of violating it.
|
||||
* Making someone else feel like an outsider or implying a lack of technical
|
||||
abilities.
|
||||
* Destructive behavior. Anything that harms Zig or another open-source project.
|
||||
|
||||
## Enforcement
|
||||
|
||||
If you need to report an issue you can contact me or Loris Cro, who are both
|
||||
paid by the Zig Software Foundation, and so moderation of this space is part of
|
||||
our job. We will swiftly remove anyone who is antagonizing others or being
|
||||
generally destructive.
|
||||
|
||||
This includes Private Harassment. If person A is directly harassed or
|
||||
antagonized by person B, person B will be blocked from participating in this
|
||||
space even if the harassment didn't take place on one of the mediums directly
|
||||
under rule of this Code of Conduct.
|
||||
|
||||
As noted, discussing this Code of Conduct should not take place on GitHub or IRC
|
||||
because these spaces are for directly working on code, not for meta-discussion.
|
||||
If you have any issues with it, you can contact me directly, or you can join one
|
||||
of the community spaces that has different rules.
|
||||
|
||||
* Andrew Kelley <andrew@ziglang.org>
|
||||
* Loris Cro <loris@ziglang.org>
|
||||
|
||||
## Conclusion
|
||||
|
||||
Thanks for reading the rules. Together, we can make this space welcoming and
|
||||
inclusive for everyone, regardless of age, body size, disability, ethnicity,
|
||||
sex characteristics, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
Sincerely,
|
||||
|
||||
Andrew ✌️
|
||||
3
.github/CONTRIBUTING.md
vendored
Normal file
3
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
Please see the
|
||||
[Contributing](https://github.com/ziglang/zig/wiki/Contributing)
|
||||
page on the wiki.
|
||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
github: [ziglang]
|
||||
@ -1,6 +1,6 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
labels: ["kind/bug"]
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
contact_links:
|
||||
- name: Language Proposal
|
||||
about: Propose to improve the Zig language
|
||||
url: https://github.com/ziglang/zig/wiki/Language-Proposals
|
||||
- name: Question
|
||||
about: Please use one of the community spaces for questions or general discussions.
|
||||
url: https://github.com/ziglang/zig/wiki/Community
|
||||
@ -1,6 +1,6 @@
|
||||
name: Error message improvement
|
||||
description: Compiler produces an unhelpful or misleading error message.
|
||||
labels: ["kind/error message"]
|
||||
labels: ["error message"]
|
||||
body:
|
||||
- type: input
|
||||
id: version
|
||||
93
.github/workflows/ci.yaml
vendored
Normal file
93
.github/workflows/ci.yaml
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
name: ci
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 0.14.x
|
||||
concurrency:
|
||||
# Cancels pending runs when a PR gets updated.
|
||||
group: ${{ github.head_ref || github.run_id }}-${{ github.actor }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
# Sets permission policy for `GITHUB_TOKEN`
|
||||
contents: read
|
||||
jobs:
|
||||
x86_64-linux-debug:
|
||||
timeout-minutes: 420
|
||||
runs-on: [self-hosted, Linux, x86_64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-linux-debug.sh
|
||||
x86_64-linux-release:
|
||||
timeout-minutes: 420
|
||||
runs-on: [self-hosted, Linux, x86_64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: sh ci/x86_64-linux-release.sh
|
||||
aarch64-linux-debug:
|
||||
timeout-minutes: 480
|
||||
runs-on: [self-hosted, Linux, aarch64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-linux-debug.sh
|
||||
aarch64-linux-release:
|
||||
timeout-minutes: 480
|
||||
runs-on: [self-hosted, Linux, aarch64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-linux-release.sh
|
||||
x86_64-macos-release:
|
||||
runs-on: "macos-13"
|
||||
env:
|
||||
ARCH: "x86_64"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: ci/x86_64-macos-release.sh
|
||||
aarch64-macos-debug:
|
||||
runs-on: [self-hosted, macOS, aarch64]
|
||||
env:
|
||||
ARCH: "aarch64"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: ci/aarch64-macos-debug.sh
|
||||
aarch64-macos-release:
|
||||
runs-on: [self-hosted, macOS, aarch64]
|
||||
env:
|
||||
ARCH: "aarch64"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: ci/aarch64-macos-release.sh
|
||||
x86_64-windows-debug:
|
||||
timeout-minutes: 420
|
||||
runs-on: [self-hosted, Windows, x86_64]
|
||||
env:
|
||||
ARCH: "x86_64"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: ci/x86_64-windows-debug.ps1
|
||||
x86_64-windows-release:
|
||||
timeout-minutes: 420
|
||||
runs-on: [self-hosted, Windows, x86_64]
|
||||
env:
|
||||
ARCH: "x86_64"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and Test
|
||||
run: ci/x86_64-windows-release.ps1
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,3 +16,7 @@ zig-out/
|
||||
/build/
|
||||
/build-*/
|
||||
/docgen_tmp/
|
||||
|
||||
# Although this was renamed to .zig-cache, let's leave it here for a few
|
||||
# releases to make it less annoying to work with multiple branches.
|
||||
zig-cache/
|
||||
|
||||
10
.mailmap
10
.mailmap
@ -4,13 +4,8 @@ Andrea Orru <andrea@orru.io> <andreaorru1991@gmail.com>
|
||||
Andrew Kelley <andrew@ziglang.org> <superjoe30@gmail.com>
|
||||
Bogdan Romanyuk <wrongnull@gmail.com> <65823030+wrongnull@users.noreply.github.com>
|
||||
Casey Banner <kcbanner@gmail.com>
|
||||
Dacheng Gao <successgdc@gmail.com>
|
||||
Daniel Kongsgaard <dakongsgaard@gmail.com>
|
||||
David Carlier <devnexen@gmail.com>
|
||||
David Rubin <david@vortan.dev>
|
||||
David Rubin <david@vortan.dev> <daviru007@icloud.com>
|
||||
David Rubin <david@vortan.dev> <87927264+Rexicon226@users.noreply.github.com>
|
||||
David Senoner <seda18@rolmail.net>
|
||||
David Rubin <daviru007@icloud.com> <87927264+Rexicon226@users.noreply.github.com>
|
||||
Dominic <4678790+dweiller@users.noreply.github.com>
|
||||
Dominic <4678790+dweiller@users.noreply.github.com> <4678790+dweiller@users.noreplay.github.com>
|
||||
Eric Eastwood <madlittlemods@gmail.com> <contact@ericeastwood.com>
|
||||
@ -31,7 +26,6 @@ Igor Anić <igor.anic@gmail.com>
|
||||
IntegratedQuantum <jahe788@gmail.com> <43880493+IntegratedQuantum@users.noreply.github.com>
|
||||
Isaac Freund <mail@isaacfreund.com> <ifreund@ifreund.xyz>
|
||||
Isaac Freund <mail@isaacfreund.com> <isaac.freund@coil.com>
|
||||
Ivan Stepanov <ivanstepanovftw@gmail.com>
|
||||
Jacob Young <amazingjacob@gmail.com>
|
||||
Jacob Young <amazingjacob@gmail.com> <jacobly0@users.noreply.github.com>
|
||||
Jacob Young <amazingjacob@gmail.com> <15544577+jacobly0@users.noreply.github.com>
|
||||
@ -44,7 +38,6 @@ Jimmi Holst Christensen <jhc@dismail.de> <jimmiholstchristensen@gmail.com>
|
||||
Jimmi Holst Christensen <jhc@dismail.de> <rainbowhejsil@gmail.com>
|
||||
Joachim Schmidt <joachim.schmidt557@outlook.com>
|
||||
Jonathan Marler <johnnymarler@gmail.com> <jonathan.j.marler@hp.com>
|
||||
Kendall Condon <goon.pri.low@gmail.com> <149842806+gooncreeper@users.noreply.github.com>
|
||||
Krzysztof Wolicki <der.teufel.mail@gmail.com>
|
||||
Krzysztof Wolicki <der.teufel.mail@gmail.com> <46651553+der-teufel-programming@users.noreply.github.com>
|
||||
LemonBoy <thatlemon@gmail.com> <LemonBoy@users.noreply.github.com>
|
||||
@ -76,7 +69,6 @@ Travis Staloch <twostepted@gmail.com>
|
||||
Travis Staloch <twostepted@gmail.com> <1562827+travisstaloch@users.noreply.github.com>
|
||||
Veikka Tuominen <git@vexu.eu>
|
||||
Veikka Tuominen <git@vexu.eu> <15308111+Vexu@users.noreply.github.com>
|
||||
Veikka Tuominen <git@vexu.eu> <veikka@ziglang.org>
|
||||
Will Lillis <will.lillis24@gmail.com>
|
||||
Will Lillis <will.lillis24@gmail.com> <wlillis@umass.edu>
|
||||
Wooster <r00ster91@proton.me>
|
||||
|
||||
215
CMakeLists.txt
215
CMakeLists.txt
@ -38,8 +38,8 @@ project(zig
|
||||
)
|
||||
|
||||
set(ZIG_VERSION_MAJOR 0)
|
||||
set(ZIG_VERSION_MINOR 16)
|
||||
set(ZIG_VERSION_PATCH 0)
|
||||
set(ZIG_VERSION_MINOR 14)
|
||||
set(ZIG_VERSION_PATCH 1)
|
||||
set(ZIG_VERSION "" CACHE STRING "Override Zig version string. Default is to find out with git.")
|
||||
|
||||
if("${ZIG_VERSION}" STREQUAL "")
|
||||
@ -133,9 +133,9 @@ else()
|
||||
set(ZIG_SYSTEM_LIBCXX "stdc++" CACHE STRING "system libcxx name for build.zig")
|
||||
endif()
|
||||
|
||||
find_package(llvm 21)
|
||||
find_package(clang 21)
|
||||
find_package(lld 21)
|
||||
find_package(llvm 19)
|
||||
find_package(clang 19)
|
||||
find_package(lld 19)
|
||||
|
||||
if(ZIG_STATIC_ZLIB)
|
||||
if (MSVC)
|
||||
@ -159,16 +159,6 @@ if(ZIG_STATIC_ZSTD)
|
||||
list(APPEND LLVM_LIBRARIES "${ZSTD}")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
# avoid linking to the debug versions of ucrt by default
|
||||
# as they are not redistributable.
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
|
||||
endif()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if(ZIG_STATIC_CURSES)
|
||||
list(REMOVE_ITEM LLVM_LIBRARIES "-lcurses")
|
||||
find_library(CURSES NAMES libcurses.a libncurses.a NAMES_PER_DIR
|
||||
@ -197,6 +187,7 @@ set(ZIG_CPP_SOURCES
|
||||
# These are planned to stay even when we are self-hosted.
|
||||
src/zig_llvm.cpp
|
||||
src/zig_llvm-ar.cpp
|
||||
src/zig_clang.cpp
|
||||
src/zig_clang_driver.cpp
|
||||
src/zig_clang_cc1_main.cpp
|
||||
src/zig_clang_cc1as_main.cpp
|
||||
@ -211,10 +202,9 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/compiler_rt/absvti2.zig
|
||||
lib/compiler_rt/adddf3.zig
|
||||
lib/compiler_rt/addf3.zig
|
||||
lib/compiler_rt/addo.zig
|
||||
lib/compiler_rt/addsf3.zig
|
||||
lib/compiler_rt/addtf3.zig
|
||||
lib/compiler_rt/addvsi3.zig
|
||||
lib/compiler_rt/addvdi3.zig
|
||||
lib/compiler_rt/addxf3.zig
|
||||
lib/compiler_rt/arm.zig
|
||||
lib/compiler_rt/atomics.zig
|
||||
@ -333,7 +323,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/compiler_rt/mulo.zig
|
||||
lib/compiler_rt/mulsf3.zig
|
||||
lib/compiler_rt/multf3.zig
|
||||
lib/compiler_rt/mulvsi3.zig
|
||||
lib/compiler_rt/mulxf3.zig
|
||||
lib/compiler_rt/negXi2.zig
|
||||
lib/compiler_rt/negdf2.zig
|
||||
@ -354,10 +343,9 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/compiler_rt/sqrt.zig
|
||||
lib/compiler_rt/stack_probe.zig
|
||||
lib/compiler_rt/subdf3.zig
|
||||
lib/compiler_rt/subo.zig
|
||||
lib/compiler_rt/subsf3.zig
|
||||
lib/compiler_rt/subtf3.zig
|
||||
lib/compiler_rt/subvdi3.zig
|
||||
lib/compiler_rt/subvsi3.zig
|
||||
lib/compiler_rt/subxf3.zig
|
||||
lib/compiler_rt/tan.zig
|
||||
lib/compiler_rt/trig.zig
|
||||
@ -385,9 +373,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/Build.zig
|
||||
lib/std/Build/Cache.zig
|
||||
lib/std/Build/Cache/DepTokenizer.zig
|
||||
lib/std/Io.zig
|
||||
lib/std/Io/Reader.zig
|
||||
lib/std/Io/Writer.zig
|
||||
lib/std/Progress.zig
|
||||
lib/std/Random.zig
|
||||
lib/std/Target.zig
|
||||
@ -412,6 +397,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/Thread/Futex.zig
|
||||
lib/std/Thread/Mutex.zig
|
||||
lib/std/Thread/Pool.zig
|
||||
lib/std/Thread/ResetEvent.zig
|
||||
lib/std/Thread/WaitGroup.zig
|
||||
lib/std/array_hash_map.zig
|
||||
lib/std/array_list.zig
|
||||
@ -434,7 +420,9 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/dwarf/OP.zig
|
||||
lib/std/dwarf/TAG.zig
|
||||
lib/std/elf.zig
|
||||
lib/std/fifo.zig
|
||||
lib/std/fmt.zig
|
||||
lib/std/fmt/format_float.zig
|
||||
lib/std/fmt/parse_float.zig
|
||||
lib/std/fs.zig
|
||||
lib/std/fs/AtomicFile.zig
|
||||
@ -448,8 +436,22 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/hash_map.zig
|
||||
lib/std/heap.zig
|
||||
lib/std/heap/arena_allocator.zig
|
||||
lib/std/io.zig
|
||||
lib/std/io/Reader.zig
|
||||
lib/std/io/Writer.zig
|
||||
lib/std/io/buffered_atomic_file.zig
|
||||
lib/std/io/buffered_writer.zig
|
||||
lib/std/io/change_detection_stream.zig
|
||||
lib/std/io/counting_reader.zig
|
||||
lib/std/io/counting_writer.zig
|
||||
lib/std/io/find_byte_writer.zig
|
||||
lib/std/io/fixed_buffer_stream.zig
|
||||
lib/std/io/limited_reader.zig
|
||||
lib/std/io/seekable_stream.zig
|
||||
lib/std/json.zig
|
||||
lib/std/json/stringify.zig
|
||||
lib/std/leb128.zig
|
||||
lib/std/linked_list.zig
|
||||
lib/std/log.zig
|
||||
lib/std/macho.zig
|
||||
lib/std/math.zig
|
||||
@ -491,7 +493,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/unicode.zig
|
||||
lib/std/zig.zig
|
||||
lib/std/zig/Ast.zig
|
||||
lib/std/zig/Ast/Render.zig
|
||||
lib/std/zig/AstGen.zig
|
||||
lib/std/zig/AstRlAnnotate.zig
|
||||
lib/std/zig/LibCInstallation.zig
|
||||
@ -499,6 +500,8 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/zig/Server.zig
|
||||
lib/std/zig/WindowsSdk.zig
|
||||
lib/std/zig/Zir.zig
|
||||
lib/std/zig/c_builtins.zig
|
||||
lib/std/zig/render.zig
|
||||
lib/std/zig/string_literal.zig
|
||||
lib/std/zig/system.zig
|
||||
lib/std/zig/system/NativePaths.zig
|
||||
@ -510,16 +513,13 @@ set(ZIG_STAGE2_SOURCES
|
||||
lib/std/zig/llvm/bitcode_writer.zig
|
||||
lib/std/zig/llvm/ir.zig
|
||||
src/Air.zig
|
||||
src/Air/Legalize.zig
|
||||
src/Air/Liveness.zig
|
||||
src/Air/Liveness/Verify.zig
|
||||
src/Air/print.zig
|
||||
src/Air/types_resolved.zig
|
||||
src/Builtin.zig
|
||||
src/Compilation.zig
|
||||
src/Compilation/Config.zig
|
||||
src/DarwinPosixSpawn.zig
|
||||
src/InternPool.zig
|
||||
src/Liveness.zig
|
||||
src/Liveness/Verify.zig
|
||||
src/Package.zig
|
||||
src/Package/Fetch.zig
|
||||
src/Package/Fetch/git.zig
|
||||
@ -529,34 +529,69 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/Sema.zig
|
||||
src/Sema/bitcast.zig
|
||||
src/Sema/comptime_ptr_access.zig
|
||||
src/ThreadSafeQueue.zig
|
||||
src/Type.zig
|
||||
src/Value.zig
|
||||
src/Zcu.zig
|
||||
src/Zcu/PerThread.zig
|
||||
src/arch/aarch64/CodeGen.zig
|
||||
src/arch/aarch64/Emit.zig
|
||||
src/arch/aarch64/Mir.zig
|
||||
src/arch/aarch64/abi.zig
|
||||
src/arch/aarch64/bits.zig
|
||||
src/arch/arm/CodeGen.zig
|
||||
src/arch/arm/Emit.zig
|
||||
src/arch/arm/Mir.zig
|
||||
src/arch/arm/abi.zig
|
||||
src/arch/arm/bits.zig
|
||||
src/arch/riscv64/abi.zig
|
||||
src/arch/riscv64/bits.zig
|
||||
src/arch/riscv64/CodeGen.zig
|
||||
src/arch/riscv64/Emit.zig
|
||||
src/arch/riscv64/encoding.zig
|
||||
src/arch/riscv64/Lower.zig
|
||||
src/arch/riscv64/Mir.zig
|
||||
src/arch/riscv64/mnem.zig
|
||||
src/arch/sparc64/CodeGen.zig
|
||||
src/arch/sparc64/Emit.zig
|
||||
src/arch/sparc64/Mir.zig
|
||||
src/arch/sparc64/abi.zig
|
||||
src/arch/sparc64/bits.zig
|
||||
src/arch/wasm/CodeGen.zig
|
||||
src/arch/wasm/Emit.zig
|
||||
src/arch/wasm/Mir.zig
|
||||
src/arch/wasm/abi.zig
|
||||
src/arch/x86/bits.zig
|
||||
src/arch/x86_64/CodeGen.zig
|
||||
src/arch/x86_64/Disassembler.zig
|
||||
src/arch/x86_64/Emit.zig
|
||||
src/arch/x86_64/Encoding.zig
|
||||
src/arch/x86_64/Lower.zig
|
||||
src/arch/x86_64/Mir.zig
|
||||
src/arch/x86_64/abi.zig
|
||||
src/arch/x86_64/bits.zig
|
||||
src/arch/x86_64/encoder.zig
|
||||
src/arch/x86_64/encodings.zon
|
||||
src/clang.zig
|
||||
src/clang_options.zig
|
||||
src/clang_options_data.zig
|
||||
src/codegen.zig
|
||||
src/codegen/aarch64.zig
|
||||
src/codegen/aarch64/abi.zig
|
||||
src/codegen/aarch64/Assemble.zig
|
||||
src/codegen/aarch64/Disassemble.zig
|
||||
src/codegen/aarch64/encoding.zig
|
||||
src/codegen/aarch64/instructions.zon
|
||||
src/codegen/aarch64/Mir.zig
|
||||
src/codegen/aarch64/Select.zig
|
||||
src/codegen/c.zig
|
||||
src/codegen/c/Type.zig
|
||||
src/codegen/llvm.zig
|
||||
src/codegen/llvm/bindings.zig
|
||||
src/codegen/spirv.zig
|
||||
src/codegen/spirv/Assembler.zig
|
||||
src/codegen/spirv/Module.zig
|
||||
src/codegen/spirv/Section.zig
|
||||
src/codegen/spirv/spec.zig
|
||||
src/crash_report.zig
|
||||
src/dev.zig
|
||||
src/libs/freebsd.zig
|
||||
src/libs/glibc.zig
|
||||
src/libs/netbsd.zig
|
||||
src/glibc.zig
|
||||
src/introspect.zig
|
||||
src/libs/libcxx.zig
|
||||
src/libs/libtsan.zig
|
||||
src/libs/libunwind.zig
|
||||
src/libcxx.zig
|
||||
src/libtsan.zig
|
||||
src/libunwind.zig
|
||||
src/link.zig
|
||||
src/link/C.zig
|
||||
src/link/Coff.zig
|
||||
@ -578,9 +613,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/link/Elf/relocatable.zig
|
||||
src/link/Elf/relocation.zig
|
||||
src/link/Elf/synthetic_sections.zig
|
||||
src/link/Elf2.zig
|
||||
src/link/LdScript.zig
|
||||
src/link/Lld.zig
|
||||
src/link/MachO.zig
|
||||
src/link/MachO/Archive.zig
|
||||
src/link/MachO/Atom.zig
|
||||
@ -607,8 +640,14 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/link/MachO/synthetic.zig
|
||||
src/link/MachO/Thunk.zig
|
||||
src/link/MachO/uuid.zig
|
||||
src/link/MappedFile.zig
|
||||
src/link/Queue.zig
|
||||
src/link/NvPtx.zig
|
||||
src/link/Plan9.zig
|
||||
src/link/Plan9/aout.zig
|
||||
src/link/SpirV.zig
|
||||
src/link/SpirV/BinaryModule.zig
|
||||
src/link/SpirV/deduplicate.zig
|
||||
src/link/SpirV/lower_invocation_globals.zig
|
||||
src/link/SpirV/prune_unused.zig
|
||||
src/link/StringTable.zig
|
||||
src/link/Wasm.zig
|
||||
src/link/Wasm/Archive.zig
|
||||
@ -624,9 +663,10 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/link/tapi/yaml.zig
|
||||
src/link/tapi/yaml/test.zig
|
||||
src/main.zig
|
||||
src/libs/mingw.zig
|
||||
src/libs/musl.zig
|
||||
src/mingw.zig
|
||||
src/musl.zig
|
||||
src/mutable_value.zig
|
||||
src/print_air.zig
|
||||
src/print_env.zig
|
||||
src/print_targets.zig
|
||||
src/print_value.zig
|
||||
@ -634,7 +674,8 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/register_manager.zig
|
||||
src/target.zig
|
||||
src/tracy.zig
|
||||
src/libs/wasi_libc.zig
|
||||
src/translate_c.zig
|
||||
src/wasi_libc.zig
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
@ -643,12 +684,6 @@ if(MSVC)
|
||||
set(ZIG_DIA_GUIDS_LIB "${MSVC_DIA_SDK_DIR}/lib/amd64/diaguids.lib")
|
||||
string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_DIA_GUIDS_LIB_ESCAPED "${ZIG_DIA_GUIDS_LIB}")
|
||||
endif()
|
||||
|
||||
# The /RTC[c][s][u] flag enables extra runtime checks. ("/RTC1" == "/RTCsu")
|
||||
# The "c" (PossibleDataLoss) and "u" (UninitializeVariable) flags trap on valid C code so we disable
|
||||
# them. The "s" flag seems like it might be OK.
|
||||
string(REPLACE "/RTC1" "/RTCs" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
string(REPLACE "/RTC1" "/RTCs" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
endif()
|
||||
|
||||
configure_file (
|
||||
@ -671,13 +706,6 @@ add_library(zigcpp STATIC ${ZIG_CPP_SOURCES})
|
||||
target_compile_features(zigcpp PRIVATE cxx_std_17)
|
||||
set_target_properties(zigcpp PROPERTIES POSITION_INDEPENDENT_CODE ${ZIG_PIE})
|
||||
|
||||
if(LLVM_LINK_MODE STREQUAL "static")
|
||||
target_compile_definitions(zigcpp PRIVATE
|
||||
LLVM_BUILD_STATIC
|
||||
CLANG_BUILD_STATIC
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
if(MINGW)
|
||||
target_compile_options(zigcpp PRIVATE -Wno-format)
|
||||
@ -731,22 +759,20 @@ endforeach()
|
||||
include(CheckSymbolExists)
|
||||
|
||||
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" ZIG_HOST_TARGET_OS)
|
||||
if(ZIG_HOST_TARGET_OS STREQUAL "android")
|
||||
set(ZIG_HOST_TARGET_OS "linux")
|
||||
set(ZIG_HOST_TARGET_IS_ANDROID TRUE)
|
||||
elseif(ZIG_HOST_TARGET_OS STREQUAL "darwin")
|
||||
if(ZIG_HOST_TARGET_OS STREQUAL "darwin")
|
||||
set(ZIG_HOST_TARGET_OS "macos")
|
||||
elseif(ZIG_HOST_TARGET_OS STREQUAL "gnu")
|
||||
set(ZIG_HOST_TARGET_OS "hurd")
|
||||
elseif(ZIG_HOST_TARGET_OS STREQUAL "serenityos")
|
||||
set(ZIG_HOST_TARGET_OS "serenity")
|
||||
elseif(ZIG_HOST_TARGET_OS STREQUAL "sunos")
|
||||
set(ZIG_HOST_TARGET_OS "illumos")
|
||||
check_symbol_exists(__illumos__ "" ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
|
||||
if (ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
|
||||
set(ZIG_HOST_TARGET_OS "illumos")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_OS "solaris")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" ZIG_HOST_TARGET_ARCH)
|
||||
if(ZIG_HOST_TARGET_ARCH MATCHES "^i[3-9]86$")
|
||||
if (ZIG_HOST_TARGET_OS STREQUAL "illumos")
|
||||
if (ZIG_HOST_TARGET_OS MATCHES "(solaris|illumos)")
|
||||
set(ZIG_HOST_TARGET_ARCH "x86_64")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_ARCH "x86")
|
||||
@ -755,12 +781,13 @@ elseif(ZIG_HOST_TARGET_ARCH STREQUAL "amd64")
|
||||
set(ZIG_HOST_TARGET_ARCH "x86_64")
|
||||
elseif(ZIG_HOST_TARGET_ARCH STREQUAL "arm64")
|
||||
set(ZIG_HOST_TARGET_ARCH "aarch64")
|
||||
elseif(ZIG_HOST_TARGET_ARCH MATCHES "^arm(el)?$" OR ZIG_HOST_TARGET_ARCH MATCHES "^armv[7-8]l$")
|
||||
elseif(ZIG_HOST_TARGET_ARCH STREQUAL "armv7l")
|
||||
set(ZIG_HOST_TARGET_ARCH "arm")
|
||||
elseif(ZIG_HOST_TARGET_ARCH STREQUAL "armeb" OR ZIG_HOST_TARGET_ARCH MATCHES "^armv[7-8]b$")
|
||||
elseif(ZIG_HOST_TARGET_ARCH STREQUAL "armv7b")
|
||||
set(ZIG_HOST_TARGET_ARCH "armeb")
|
||||
endif()
|
||||
if(ZIG_HOST_TARGET_ARCH MATCHES "^arm(eb)?$")
|
||||
string(REGEX REPLACE "^((arm|thumb)(hf?)?)el$" "\\1" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
|
||||
if(ZIG_HOST_TARGET_ARCH MATCHES "^arm(hf?)?(eb)?$")
|
||||
check_symbol_exists(__thumb__ "" ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
|
||||
if(ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
|
||||
string(REGEX REPLACE "^arm" "thumb" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
|
||||
@ -768,17 +795,15 @@ if(ZIG_HOST_TARGET_ARCH MATCHES "^arm(eb)?$")
|
||||
endif()
|
||||
string(REGEX REPLACE "^ppc((64)?(le)?)$" "powerpc\\1" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
|
||||
|
||||
set(ZIG_HOST_TARGET_ABI "")
|
||||
if(MSVC)
|
||||
set(ZIG_HOST_TARGET_ABI "-msvc")
|
||||
elseif(MINGW)
|
||||
set(ZIG_HOST_TARGET_ABI "-gnu")
|
||||
elseif(ZIG_HOST_TARGET_IS_ANDROID)
|
||||
if(ZIG_HOST_TARGET_ARCH STREQUAL "arm")
|
||||
set(ZIG_HOST_TARGET_ABI "-androideabi")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_ABI "-android")
|
||||
endif()
|
||||
elseif(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)hf?(eb)?$")
|
||||
string(REGEX REPLACE "^(arm|thumb)hf?((eb)?)$" "\\1\\2" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
|
||||
set(ZIG_HOST_TARGET_ABI "-eabihf")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_ABI "")
|
||||
endif()
|
||||
|
||||
set(ZIG_HOST_TARGET_TRIPLE "${ZIG_HOST_TARGET_ARCH}-${ZIG_HOST_TARGET_OS}${ZIG_HOST_TARGET_ABI}" CACHE STRING "Host zig target triple.")
|
||||
@ -791,7 +816,7 @@ if(MSVC)
|
||||
else()
|
||||
set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")
|
||||
set(ZIG1_COMPILE_FLAGS "-std=c99 -Os")
|
||||
set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector")
|
||||
set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-stack-protector")
|
||||
if(APPLE)
|
||||
set(ZIG2_LINK_FLAGS "-Wl,-stack_size,0x10000000")
|
||||
elseif(MINGW)
|
||||
@ -920,24 +945,12 @@ if(ZIG_EXTRA_BUILD_ARGS)
|
||||
list(APPEND ZIG_BUILD_ARGS ${ZIG_EXTRA_BUILD_ARGS})
|
||||
endif()
|
||||
|
||||
set(ZIG_RELEASE_SAFE OFF CACHE BOOL "Build Zig as ReleaseSafe (with debug assertions on)")
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=Debug)
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast)
|
||||
else()
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseSmall)
|
||||
else()
|
||||
# Release and RelWithDebInfo
|
||||
if(ZIG_RELEASE_SAFE)
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseSafe)
|
||||
else()
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast)
|
||||
endif()
|
||||
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
||||
list(APPEND ZIG_BUILD_ARGS -Dstrip)
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast -Dstrip)
|
||||
endif()
|
||||
|
||||
if(ZIG_STATIC AND NOT MSVC)
|
||||
@ -960,6 +973,10 @@ if(NOT "${ZIG_TARGET_DYNAMIC_LINKER}" STREQUAL "")
|
||||
list(APPEND ZIG_BUILD_ARGS "-Ddynamic-linker=${ZIG_TARGET_DYNAMIC_LINKER}")
|
||||
endif()
|
||||
|
||||
if(MINGW AND "${ZIG_HOST_TARGET_ARCH}" STREQUAL "x86")
|
||||
list(APPEND ZIG_BUILD_ARGS --maxrss 7000000000)
|
||||
endif()
|
||||
|
||||
|
||||
add_custom_target(stage3 ALL
|
||||
DEPENDS "${PROJECT_BINARY_DIR}/stage3/bin/zig"
|
||||
|
||||
148
README.md
148
README.md
@ -1,3 +1,147 @@
|
||||
[Moved to Codeberg](https://ziglang.org/news/migrating-from-github-to-codeberg/)
|
||||

|
||||
|
||||
**This repository is not mirrored.**
|
||||
A general-purpose programming language and toolchain for maintaining
|
||||
**robust**, **optimal**, and **reusable** software.
|
||||
|
||||
https://ziglang.org/
|
||||
|
||||
## Documentation
|
||||
|
||||
If you are looking at this README file in a source tree, please refer to the
|
||||
**Release Notes**, **Language Reference**, or **Standard Library
|
||||
Documentation** corresponding to the version of Zig that you are using by
|
||||
following the appropriate link on the
|
||||
[download page](https://ziglang.org/download).
|
||||
|
||||
Otherwise, you're looking at a release of Zig, so you can find the language
|
||||
reference at `doc/langref.html`, and the standard library documentation by
|
||||
running `zig std`, which will open a browser tab.
|
||||
|
||||
## Installation
|
||||
|
||||
* [download a pre-built binary](https://ziglang.org/download/)
|
||||
* [install from a package manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager)
|
||||
* [bootstrap zig for any target](https://github.com/ziglang/zig-bootstrap)
|
||||
|
||||
A Zig installation is composed of two things:
|
||||
|
||||
1. The Zig executable
|
||||
2. The lib/ directory
|
||||
|
||||
At runtime, the executable searches up the file system for the lib/ directory,
|
||||
relative to itself:
|
||||
|
||||
* lib/
|
||||
* lib/zig/
|
||||
* ../lib/
|
||||
* ../lib/zig/
|
||||
* (and so on)
|
||||
|
||||
In other words, you can **unpack a release of Zig anywhere**, and then begin
|
||||
using it immediately. There is no need to install it globally, although this
|
||||
mechanism supports that use case too (i.e. `/usr/bin/zig` and `/usr/lib/zig/`).
|
||||
|
||||
## Building from Source
|
||||
|
||||
Ensure you have the required dependencies:
|
||||
|
||||
* CMake >= 3.15
|
||||
* System C/C++ Toolchain
|
||||
* LLVM, Clang, LLD development libraries == 19.x
|
||||
|
||||
Then it is the standard CMake build process:
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make install
|
||||
```
|
||||
|
||||
For more options, tips, and troubleshooting, please see the
|
||||
[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)
|
||||
page on the wiki.
|
||||
|
||||
## Building from Source without LLVM
|
||||
|
||||
In this case, the only system dependency is a C compiler.
|
||||
|
||||
```
|
||||
cc -o bootstrap bootstrap.c
|
||||
./bootstrap
|
||||
```
|
||||
|
||||
This produces a `zig2` executable in the current working directory. This is a
|
||||
"stage2" build of the compiler,
|
||||
[without LLVM extensions](https://github.com/ziglang/zig/issues/16270), and is
|
||||
therefore lacking these features:
|
||||
- Release mode optimizations
|
||||
- [aarch64 machine code backend](https://github.com/ziglang/zig/issues/21172)
|
||||
- [@cImport](https://github.com/ziglang/zig/issues/20630)
|
||||
- [zig translate-c](https://github.com/ziglang/zig/issues/20875)
|
||||
- [Ability to compile assembly files](https://github.com/ziglang/zig/issues/21169)
|
||||
- [Some ELF linking features](https://github.com/ziglang/zig/issues/17749)
|
||||
- [Most COFF/PE linking features](https://github.com/ziglang/zig/issues/17751)
|
||||
- [Some WebAssembly linking features](https://github.com/ziglang/zig/issues/17750)
|
||||
- [Ability to create import libs from def files](https://github.com/ziglang/zig/issues/17807)
|
||||
- [Ability to create static archives from object files](https://github.com/ziglang/zig/issues/9828)
|
||||
- Ability to compile C, C++, Objective-C, and Objective-C++ files
|
||||
|
||||
However, a compiler built this way does provide a C backend, which may be
|
||||
useful for creating system packages of Zig projects using the system C
|
||||
toolchain. **In this case, LLVM is not needed!**
|
||||
|
||||
Furthermore, a compiler built this way provides an LLVM backend that produces
|
||||
bitcode files, which may be compiled into object files via a system Clang
|
||||
package. This can be used to produce system packages of Zig applications
|
||||
without the Zig package dependency on LLVM.
|
||||
|
||||
## Contributing
|
||||
|
||||
[Donate monthly](https://ziglang.org/zsf/).
|
||||
|
||||
Zig is Free and Open Source Software. We welcome bug reports and patches from
|
||||
everyone. However, keep in mind that Zig governance is BDFN (Benevolent
|
||||
Dictator For Now) which means that Andrew Kelley has final say on the design
|
||||
and implementation of everything.
|
||||
|
||||
One of the best ways you can contribute to Zig is to start using it for an
|
||||
open-source personal project.
|
||||
|
||||
This leads to discovering bugs and helps flesh out use cases, which lead to
|
||||
further design iterations of Zig. Importantly, each issue found this way comes
|
||||
with real world motivations, making it straightforward to explain the reasoning
|
||||
behind proposals and feature requests.
|
||||
|
||||
You will be taken much more seriously on the issue tracker if you have a
|
||||
personal project that uses Zig.
|
||||
|
||||
The issue label
|
||||
[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22)
|
||||
exists to help you find issues that are **limited in scope and/or knowledge of
|
||||
Zig internals.**
|
||||
|
||||
Please note that issues labeled
|
||||
[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal)
|
||||
but do not also have the
|
||||
[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted)
|
||||
label are still under consideration, and efforts to implement such a proposal
|
||||
have a high risk of being wasted. If you are interested in a proposal which is
|
||||
still under consideration, please express your interest in the issue tracker,
|
||||
providing extra insights and considerations that others have not yet expressed.
|
||||
The most highly regarded argument in such a discussion is a real world use case.
|
||||
|
||||
For more tips, please see the
|
||||
[Contributing](https://github.com/ziglang/zig/wiki/Contributing) page on the
|
||||
wiki.
|
||||
|
||||
## Community
|
||||
|
||||
The Zig community is decentralized. Anyone is free to start and maintain their
|
||||
own space for Zig users to gather. There is no concept of "official" or
|
||||
"unofficial". Each gathering place has its own moderators and rules. Users are
|
||||
encouraged to be aware of the social structures of the spaces they inhabit, and
|
||||
work purposefully to facilitate spaces that align with their values.
|
||||
|
||||
Please see the [Community](https://github.com/ziglang/zig/wiki/Community) wiki
|
||||
page for a public listing of social spaces.
|
||||
|
||||
@ -64,8 +64,6 @@ static const char *get_host_os(void) {
|
||||
return "linux";
|
||||
#elif defined(__FreeBSD__)
|
||||
return "freebsd";
|
||||
#elif defined(__DragonFly__)
|
||||
return "dragonfly";
|
||||
#elif defined(__HAIKU__)
|
||||
return "haiku";
|
||||
#else
|
||||
|
||||
248
build.zig
248
build.zig
@ -3,6 +3,7 @@ const builtin = std.builtin;
|
||||
const tests = @import("test/tests.zig");
|
||||
const BufMap = std.BufMap;
|
||||
const mem = std.mem;
|
||||
const ArrayList = std.ArrayList;
|
||||
const io = std.io;
|
||||
const fs = std.fs;
|
||||
const InstallDirectoryOptions = std.Build.InstallDirectoryOptions;
|
||||
@ -10,7 +11,7 @@ const assert = std.debug.assert;
|
||||
const DevEnv = @import("src/dev.zig").Env;
|
||||
const ValueInterpretMode = enum { direct, by_name };
|
||||
|
||||
const zig_version: std.SemanticVersion = .{ .major = 0, .minor = 16, .patch = 0 };
|
||||
const zig_version: std.SemanticVersion = .{ .major = 0, .minor = 14, .patch = 1 };
|
||||
const stack_size = 46 * 1024 * 1024;
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
@ -81,23 +82,16 @@ pub fn build(b: *std.Build) !void {
|
||||
docs_step.dependOn(langref_step);
|
||||
docs_step.dependOn(std_docs_step);
|
||||
|
||||
const no_matrix = b.option(bool, "no-matrix", "Limit test matrix to exactly one target configuration") orelse false;
|
||||
const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;
|
||||
const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse no_matrix;
|
||||
const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
|
||||
const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
|
||||
const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;
|
||||
const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release;
|
||||
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse no_matrix;
|
||||
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
|
||||
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
|
||||
const skip_single_threaded = b.option(bool, "skip-single-threaded", "Main test suite skips tests that are single-threaded") orelse false;
|
||||
const skip_compile_errors = b.option(bool, "skip-compile-errors", "Main test suite skips compile error tests") orelse false;
|
||||
const skip_freebsd = b.option(bool, "skip-freebsd", "Main test suite skips targets with freebsd OS") orelse false;
|
||||
const skip_netbsd = b.option(bool, "skip-netbsd", "Main test suite skips targets with netbsd OS") orelse false;
|
||||
const skip_windows = b.option(bool, "skip-windows", "Main test suite skips targets with windows OS") orelse false;
|
||||
const skip_darwin = b.option(bool, "skip-darwin", "Main test suite skips targets with darwin OSs") orelse false;
|
||||
const skip_linux = b.option(bool, "skip-linux", "Main test suite skips targets with linux OS") orelse false;
|
||||
const skip_llvm = b.option(bool, "skip-llvm", "Main test suite skips targets that use LLVM backend") orelse false;
|
||||
const skip_test_incremental = b.option(bool, "skip-test-incremental", "Main test step omits dependency on test-incremental step") orelse false;
|
||||
const skip_translate_c = b.option(bool, "skip-translate-c", "Main test suite skips translate-c tests") orelse false;
|
||||
const skip_run_translated_c = b.option(bool, "skip-run-translated-c", "Main test suite skips run-translated-c tests") orelse false;
|
||||
|
||||
const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
|
||||
|
||||
@ -202,11 +196,12 @@ pub fn build(b: *std.Build) !void {
|
||||
});
|
||||
exe.pie = pie;
|
||||
exe.entitlements = entitlements;
|
||||
exe.use_new_linker = b.option(bool, "new-linker", "Use the new linker");
|
||||
|
||||
const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");
|
||||
exe.use_llvm = use_llvm;
|
||||
exe.use_lld = use_llvm;
|
||||
exe.build_id = b.option(
|
||||
std.zig.BuildId,
|
||||
"build-id",
|
||||
"Request creation of '.note.gnu.build-id' section",
|
||||
);
|
||||
|
||||
if (no_bin) {
|
||||
b.getInstallStep().dependOn(&exe.step);
|
||||
@ -219,6 +214,10 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
test_step.dependOn(&exe.step);
|
||||
|
||||
const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");
|
||||
exe.use_llvm = use_llvm;
|
||||
exe.use_lld = use_llvm;
|
||||
|
||||
const exe_options = b.addOptions();
|
||||
exe.root_module.addOptions("build_options", exe_options);
|
||||
|
||||
@ -262,7 +261,7 @@ pub fn build(b: *std.Build) !void {
|
||||
};
|
||||
const git_describe = mem.trim(u8, git_describe_untrimmed, " \n\r");
|
||||
|
||||
switch (mem.countScalar(u8, git_describe, '-')) {
|
||||
switch (mem.count(u8, git_describe, "-")) {
|
||||
0 => {
|
||||
// Tagged release version (e.g. 0.10.0).
|
||||
if (!mem.eql(u8, git_describe, version_string)) {
|
||||
@ -280,7 +279,7 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
const ancestor_ver = try std.SemanticVersion.parse(tagged_ancestor);
|
||||
if (zig_version.order(ancestor_ver) != .gt) {
|
||||
std.debug.print("Zig version '{f}' must be greater than tagged ancestor '{f}'\n", .{ zig_version, ancestor_ver });
|
||||
std.debug.print("Zig version '{}' must be greater than tagged ancestor '{}'\n", .{ zig_version, ancestor_ver });
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
@ -305,7 +304,7 @@ pub fn build(b: *std.Build) !void {
|
||||
if (enable_llvm) {
|
||||
const cmake_cfg = if (static_llvm) null else blk: {
|
||||
if (findConfigH(b, config_h_path_option)) |config_h_path| {
|
||||
const file_contents = fs.cwd().readFileAlloc(config_h_path, b.allocator, .limited(max_config_h_bytes)) catch unreachable;
|
||||
const file_contents = fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable;
|
||||
break :blk parseConfigH(b, file_contents);
|
||||
} else {
|
||||
std.log.warn("config.h could not be located automatically. Consider providing it explicitly via \"-Dconfig_h\"", .{});
|
||||
@ -377,7 +376,7 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
|
||||
const test_target_filters = b.option([]const []const u8, "test-target-filter", "Skip tests whose target triple do not match any filter") orelse &[0][]const u8{};
|
||||
const test_extra_targets = b.option(bool, "test-extra-targets", "Enable running module tests for additional targets") orelse false;
|
||||
const test_slow_targets = b.option(bool, "test-slow-targets", "Enable running module tests for targets that have a slow compiler backend") orelse false;
|
||||
|
||||
var chosen_opt_modes_buf: [4]builtin.OptimizeMode = undefined;
|
||||
var chosen_mode_index: usize = 0;
|
||||
@ -416,18 +415,9 @@ pub fn build(b: *std.Build) !void {
|
||||
test_step.dependOn(check_fmt);
|
||||
|
||||
const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
|
||||
try tests.addCases(b, test_cases_step, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.skip_compile_errors = skip_compile_errors,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_libc = skip_libc,
|
||||
try tests.addCases(b, test_cases_step, test_filters, test_target_filters, target, .{
|
||||
.skip_translate_c = skip_translate_c,
|
||||
.skip_run_translated_c = skip_run_translated_c,
|
||||
}, .{
|
||||
.enable_llvm = enable_llvm,
|
||||
.llvm_has_m68k = llvm_has_m68k,
|
||||
@ -443,7 +433,7 @@ pub fn build(b: *std.Build) !void {
|
||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.test_extra_targets = test_extra_targets,
|
||||
.test_slow_targets = test_slow_targets,
|
||||
.root_src = "test/behavior.zig",
|
||||
.name = "behavior",
|
||||
.desc = "Run the behavior tests",
|
||||
@ -451,22 +441,30 @@ pub fn build(b: *std.Build) !void {
|
||||
.include_paths = &.{},
|
||||
.skip_single_threaded = skip_single_threaded,
|
||||
.skip_non_native = skip_non_native,
|
||||
.test_default_only = no_matrix,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_libc = skip_libc,
|
||||
// 3888779264 was observed on an x86_64-linux-gnu host.
|
||||
.max_rss = 4000000000,
|
||||
.use_llvm = use_llvm,
|
||||
.max_rss = 2 * 1024 * 1024 * 1024,
|
||||
}));
|
||||
|
||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.test_extra_targets = test_extra_targets,
|
||||
.test_slow_targets = test_slow_targets,
|
||||
.root_src = "test/c_import.zig",
|
||||
.name = "c-import",
|
||||
.desc = "Run the @cImport tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{"test/c_import"},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_libc = skip_libc,
|
||||
.use_llvm = use_llvm,
|
||||
}));
|
||||
|
||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.test_slow_targets = test_slow_targets,
|
||||
.root_src = "lib/compiler_rt.zig",
|
||||
.name = "compiler-rt",
|
||||
.desc = "Run the compiler_rt tests",
|
||||
@ -474,43 +472,31 @@ pub fn build(b: *std.Build) !void {
|
||||
.include_paths = &.{},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.test_default_only = no_matrix,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_libc = true,
|
||||
.use_llvm = use_llvm,
|
||||
.no_builtin = true,
|
||||
}));
|
||||
|
||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.test_extra_targets = test_extra_targets,
|
||||
.test_slow_targets = test_slow_targets,
|
||||
.root_src = "lib/c.zig",
|
||||
.name = "zigc",
|
||||
.desc = "Run the zigc tests",
|
||||
.name = "universal-libc",
|
||||
.desc = "Run the universal libc tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.test_default_only = no_matrix,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_libc = true,
|
||||
.use_llvm = use_llvm,
|
||||
.no_builtin = true,
|
||||
}));
|
||||
|
||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
.test_extra_targets = test_extra_targets,
|
||||
.test_slow_targets = test_slow_targets,
|
||||
.root_src = "lib/std/std.zig",
|
||||
.name = "std",
|
||||
.desc = "Run the standard library tests",
|
||||
@ -518,14 +504,8 @@ pub fn build(b: *std.Build) !void {
|
||||
.include_paths = &.{},
|
||||
.skip_single_threaded = skip_single_threaded,
|
||||
.skip_non_native = skip_non_native,
|
||||
.test_default_only = no_matrix,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_libc = skip_libc,
|
||||
.use_llvm = use_llvm,
|
||||
// I observed a value of 5605064704 on the M2 CI.
|
||||
.max_rss = 6165571174,
|
||||
}));
|
||||
@ -534,9 +514,11 @@ pub fn build(b: *std.Build) !void {
|
||||
test_step.dependOn(unit_tests_step);
|
||||
|
||||
const unit_tests = b.addTest(.{
|
||||
.root_module = addCompilerMod(b, .{
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
.link_libc = link_libc,
|
||||
.single_threaded = single_threaded,
|
||||
}),
|
||||
.filters = test_filters,
|
||||
@ -544,12 +526,10 @@ pub fn build(b: *std.Build) !void {
|
||||
.use_lld = use_llvm,
|
||||
.zig_lib_dir = b.path("lib"),
|
||||
});
|
||||
if (link_libc) {
|
||||
unit_tests.root_module.link_libc = true;
|
||||
}
|
||||
unit_tests.root_module.addOptions("build_options", exe_options);
|
||||
unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step);
|
||||
|
||||
test_step.dependOn(tests.addCompareOutputTests(b, test_filters, optimization_modes));
|
||||
test_step.dependOn(tests.addStandaloneTests(
|
||||
b,
|
||||
optimization_modes,
|
||||
@ -560,18 +540,12 @@ pub fn build(b: *std.Build) !void {
|
||||
test_step.dependOn(tests.addCAbiTests(b, .{
|
||||
.test_target_filters = test_target_filters,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
.skip_netbsd = skip_netbsd,
|
||||
.skip_windows = skip_windows,
|
||||
.skip_darwin = skip_darwin,
|
||||
.skip_linux = skip_linux,
|
||||
.skip_llvm = skip_llvm,
|
||||
.skip_release = skip_release,
|
||||
}));
|
||||
test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
|
||||
test_step.dependOn(tests.addStackTraceTests(b, test_filters, skip_non_native));
|
||||
test_step.dependOn(tests.addErrorTraceTests(b, test_filters, optimization_modes, skip_non_native));
|
||||
test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
|
||||
test_step.dependOn(tests.addCliTests(b));
|
||||
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
|
||||
if (tests.addDebuggerTests(b, .{
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
@ -579,13 +553,9 @@ pub fn build(b: *std.Build) !void {
|
||||
.lldb = b.option([]const u8, "lldb", "path to lldb binary"),
|
||||
.optimize_modes = optimization_modes,
|
||||
.skip_single_threaded = skip_single_threaded,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_libc = skip_libc,
|
||||
})) |test_debugger_step| test_step.dependOn(test_debugger_step);
|
||||
if (tests.addLlvmIrTests(b, .{
|
||||
.enable_llvm = enable_llvm,
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
})) |test_llvm_ir_step| test_step.dependOn(test_llvm_ir_step);
|
||||
|
||||
try addWasiUpdateStep(b, version);
|
||||
|
||||
@ -610,15 +580,7 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
const test_incremental_step = b.step("test-incremental", "Run the incremental compilation test cases");
|
||||
try tests.addIncrementalTests(b, test_incremental_step);
|
||||
if (!skip_test_incremental) test_step.dependOn(test_incremental_step);
|
||||
|
||||
if (tests.addLibcTests(b, .{
|
||||
.optimize_modes = optimization_modes,
|
||||
.test_filters = test_filters,
|
||||
.test_target_filters = test_target_filters,
|
||||
// Highest RSS observed in any test case was exactly 1802878976 on x86_64-linux.
|
||||
.max_rss = 2253598720,
|
||||
})) |test_libc_step| test_step.dependOn(test_libc_step);
|
||||
test_step.dependOn(test_incremental_step);
|
||||
}
|
||||
|
||||
fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
|
||||
@ -679,17 +641,17 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
|
||||
});
|
||||
run_opt.addArtifactArg(exe);
|
||||
run_opt.addArg("-o");
|
||||
const optimized_wasm = run_opt.addOutputFileArg("zig1.wasm");
|
||||
run_opt.addFileArg(b.path("stage1/zig1.wasm"));
|
||||
|
||||
const update_zig1 = b.addUpdateSourceFiles();
|
||||
update_zig1.addCopyFileToSource(optimized_wasm, "stage1/zig1.wasm");
|
||||
update_zig1.addCopyFileToSource(b.path("lib/zig.h"), "stage1/zig.h");
|
||||
const copy_zig_h = b.addUpdateSourceFiles();
|
||||
copy_zig_h.addCopyFileToSource(b.path("lib/zig.h"), "stage1/zig.h");
|
||||
|
||||
const update_zig1_step = b.step("update-zig1", "Update stage1/zig1.wasm");
|
||||
update_zig1_step.dependOn(&update_zig1.step);
|
||||
update_zig1_step.dependOn(&run_opt.step);
|
||||
update_zig1_step.dependOn(©_zig_h.step);
|
||||
}
|
||||
|
||||
const AddCompilerModOptions = struct {
|
||||
const AddCompilerStepOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
target: std.Build.ResolvedTarget,
|
||||
strip: ?bool = null,
|
||||
@ -698,7 +660,7 @@ const AddCompilerModOptions = struct {
|
||||
single_threaded: ?bool = null,
|
||||
};
|
||||
|
||||
fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Module {
|
||||
fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile {
|
||||
const compiler_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = options.target,
|
||||
@ -706,6 +668,24 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
|
||||
.strip = options.strip,
|
||||
.sanitize_thread = options.sanitize_thread,
|
||||
.single_threaded = options.single_threaded,
|
||||
.code_model = switch (options.target.result.cpu.arch) {
|
||||
// NB:
|
||||
// For loongarch, LLVM supports only small, medium and large
|
||||
// code model. If we don't explicitly specify the code model,
|
||||
// the default value `small' will be used.
|
||||
//
|
||||
// Since zig binary itself is relatively large, using a `small'
|
||||
// code model will cause
|
||||
//
|
||||
// relocation R_LARCH_B26 out of range
|
||||
//
|
||||
// error when linking a loongarch32/loongarch64 zig binary.
|
||||
//
|
||||
// Here we explicitly set code model to `medium' to avoid this
|
||||
// error.
|
||||
.loongarch32, .loongarch64 => .medium,
|
||||
else => .default,
|
||||
},
|
||||
.valgrind = options.valgrind,
|
||||
});
|
||||
|
||||
@ -713,16 +693,18 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
|
||||
.root_source_file = b.path("lib/compiler/aro/aro.zig"),
|
||||
});
|
||||
|
||||
const aro_translate_c_mod = b.createModule(.{
|
||||
.root_source_file = b.path("lib/compiler/aro_translate_c.zig"),
|
||||
});
|
||||
|
||||
aro_translate_c_mod.addImport("aro", aro_mod);
|
||||
compiler_mod.addImport("aro", aro_mod);
|
||||
compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
|
||||
|
||||
return compiler_mod;
|
||||
}
|
||||
|
||||
fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "zig",
|
||||
.max_rss = 7_800_000_000,
|
||||
.root_module = addCompilerMod(b, options),
|
||||
.root_module = compiler_mod,
|
||||
});
|
||||
exe.stack_size = stack_size;
|
||||
|
||||
@ -742,9 +724,6 @@ const exe_cflags = [_][]const u8{
|
||||
"-Wno-type-limits",
|
||||
"-Wno-missing-braces",
|
||||
"-Wno-comment",
|
||||
// `exe_cflags` is only used for static linking.
|
||||
"-DLLVM_BUILD_STATIC",
|
||||
"-DCLANG_BUILD_STATIC",
|
||||
};
|
||||
|
||||
fn addCmakeCfgOptionsToExe(
|
||||
@ -754,7 +733,7 @@ fn addCmakeCfgOptionsToExe(
|
||||
use_zig_libcxx: bool,
|
||||
) !void {
|
||||
const mod = exe.root_module;
|
||||
const target = &mod.resolved_target.?.result;
|
||||
const target = mod.resolved_target.?.result;
|
||||
|
||||
if (target.os.tag.isDarwin()) {
|
||||
// useful for package maintainers
|
||||
@ -819,7 +798,7 @@ fn addCmakeCfgOptionsToExe(
|
||||
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
if (static) try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
},
|
||||
.illumos => {
|
||||
.solaris, .illumos => {
|
||||
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
},
|
||||
@ -907,7 +886,7 @@ fn addCxxKnownPath(
|
||||
return error.RequiredLibraryNotFound;
|
||||
|
||||
const path_padded = run: {
|
||||
var args = std.array_list.Managed([]const u8).init(b.allocator);
|
||||
var args = std.ArrayList([]const u8).init(b.allocator);
|
||||
try args.append(ctx.cxx_compiler);
|
||||
var it = std.mem.tokenizeAny(u8, ctx.cxx_compiler_arg1, &std.ascii.whitespace);
|
||||
while (it.next()) |arg| try args.append(arg);
|
||||
@ -1133,6 +1112,7 @@ fn toNativePathSep(b: *std.Build, s: []const u8) []u8 {
|
||||
const zig_cpp_sources = [_][]const u8{
|
||||
// These are planned to stay even when we are self-hosted.
|
||||
"src/zig_llvm.cpp",
|
||||
"src/zig_clang.cpp",
|
||||
"src/zig_llvm-ar.cpp",
|
||||
"src/zig_clang_driver.cpp",
|
||||
"src/zig_clang_cc1_main.cpp",
|
||||
@ -1158,6 +1138,7 @@ const clang_libs = [_][]const u8{
|
||||
"clangBasic",
|
||||
"clangEdit",
|
||||
"clangLex",
|
||||
"clangARCMigrate",
|
||||
"clangRewriteFrontend",
|
||||
"clangRewrite",
|
||||
"clangCrossTU",
|
||||
@ -1185,10 +1166,10 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMXRay",
|
||||
"LLVMLibDriver",
|
||||
"LLVMDlltoolDriver",
|
||||
"LLVMTelemetry",
|
||||
"LLVMTextAPIBinaryReader",
|
||||
"LLVMCoverage",
|
||||
"LLVMLineEditor",
|
||||
"LLVMSandboxIR",
|
||||
"LLVMXCoreDisassembler",
|
||||
"LLVMXCoreCodeGen",
|
||||
"LLVMXCoreDesc",
|
||||
@ -1215,10 +1196,6 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMSystemZCodeGen",
|
||||
"LLVMSystemZDesc",
|
||||
"LLVMSystemZInfo",
|
||||
"LLVMSPIRVCodeGen",
|
||||
"LLVMSPIRVDesc",
|
||||
"LLVMSPIRVInfo",
|
||||
"LLVMSPIRVAnalysis",
|
||||
"LLVMSparcDisassembler",
|
||||
"LLVMSparcAsmParser",
|
||||
"LLVMSparcCodeGen",
|
||||
@ -1303,34 +1280,32 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMOrcTargetProcess",
|
||||
"LLVMOrcShared",
|
||||
"LLVMDWP",
|
||||
"LLVMDWARFCFIChecker",
|
||||
"LLVMDebugInfoLogicalView",
|
||||
"LLVMDebugInfoGSYM",
|
||||
"LLVMOption",
|
||||
"LLVMObjectYAML",
|
||||
"LLVMObjCopy",
|
||||
"LLVMMCA",
|
||||
"LLVMMCDisassembler",
|
||||
"LLVMLTO",
|
||||
"LLVMPasses",
|
||||
"LLVMHipStdPar",
|
||||
"LLVMCFGuard",
|
||||
"LLVMCoroutines",
|
||||
"LLVMipo",
|
||||
"LLVMVectorize",
|
||||
"LLVMLinker",
|
||||
"LLVMInstrumentation",
|
||||
"LLVMFrontendOpenMP",
|
||||
"LLVMFrontendOffloading",
|
||||
"LLVMFrontendOpenACC",
|
||||
"LLVMFrontendHLSL",
|
||||
"LLVMFrontendDriver",
|
||||
"LLVMExtensions",
|
||||
"LLVMPasses",
|
||||
"LLVMHipStdPar",
|
||||
"LLVMCoroutines",
|
||||
"LLVMCFGuard",
|
||||
"LLVMipo",
|
||||
"LLVMInstrumentation",
|
||||
"LLVMVectorize",
|
||||
"LLVMSandboxIR",
|
||||
"LLVMLinker",
|
||||
"LLVMFrontendOpenMP",
|
||||
"LLVMFrontendDirective",
|
||||
"LLVMFrontendAtomic",
|
||||
"LLVMFrontendOffloading",
|
||||
"LLVMObjectYAML",
|
||||
"LLVMDWARFLinkerParallel",
|
||||
"LLVMDWARFLinkerClassic",
|
||||
"LLVMDWARFLinker",
|
||||
"LLVMCodeGenData",
|
||||
"LLVMGlobalISel",
|
||||
"LLVMMIRParser",
|
||||
"LLVMAsmPrinter",
|
||||
@ -1339,7 +1314,6 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMTarget",
|
||||
"LLVMObjCARCOpts",
|
||||
"LLVMCodeGenTypes",
|
||||
"LLVMCGData",
|
||||
"LLVMIRPrinter",
|
||||
"LLVMInterfaceStub",
|
||||
"LLVMFileCheck",
|
||||
@ -1355,16 +1329,14 @@ const llvm_libs = [_][]const u8{
|
||||
"LLVMDebugInfoBTF",
|
||||
"LLVMDebugInfoPDB",
|
||||
"LLVMDebugInfoMSF",
|
||||
"LLVMDebugInfoCodeView",
|
||||
"LLVMDebugInfoGSYM",
|
||||
"LLVMDebugInfoDWARF",
|
||||
"LLVMDebugInfoDWARFLowLevel",
|
||||
"LLVMObject",
|
||||
"LLVMTextAPI",
|
||||
"LLVMMCParser",
|
||||
"LLVMIRReader",
|
||||
"LLVMAsmParser",
|
||||
"LLVMMC",
|
||||
"LLVMDebugInfoCodeView",
|
||||
"LLVMBitReader",
|
||||
"LLVMFuzzerCLI",
|
||||
"LLVMCore",
|
||||
@ -1414,7 +1386,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
|
||||
});
|
||||
|
||||
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
|
||||
std.debug.panic("unable to open '{f}doc/langref' directory: {s}", .{
|
||||
std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{
|
||||
b.build_root, @errorName(err),
|
||||
});
|
||||
};
|
||||
@ -1435,7 +1407,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
|
||||
// in a temporary directory
|
||||
"--cache-root", b.cache_root.path orelse ".",
|
||||
});
|
||||
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) });
|
||||
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{}", .{b.graph.zig_lib_directory}) });
|
||||
cmd.addArgs(&.{"-i"});
|
||||
cmd.addFileArg(b.path(b.fmt("doc/langref/{s}", .{entry.name})));
|
||||
|
||||
|
||||
@ -5,14 +5,20 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="aarch64-linux-musl"
|
||||
ARCH="$(uname -m)"
|
||||
TARGET="$ARCH-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/local/bin:$PATH"
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -44,14 +50,12 @@ ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 44918199637 \
|
||||
--maxrss 24696061952 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-superhtml \
|
||||
--test-timeout 3m
|
||||
-Denable-superhtml
|
||||
|
||||
stage3-debug/bin/zig build \
|
||||
--prefix stage4-debug \
|
||||
|
||||
@ -5,14 +5,20 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="aarch64-linux-musl"
|
||||
ARCH="$(uname -m)"
|
||||
TARGET="$ARCH-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/local/bin:$PATH"
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -44,14 +50,12 @@ ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-release/bin/zig build test docs \
|
||||
--maxrss 44918199637 \
|
||||
--maxrss 24696061952 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-superhtml \
|
||||
--test-timeout 3m
|
||||
-Denable-superhtml
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
|
||||
@ -3,10 +3,13 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
# Script assumes the presence of the following:
|
||||
# s3cmd
|
||||
|
||||
ZIGDIR="$PWD"
|
||||
TARGET="aarch64-macos-none"
|
||||
TARGET="$ARCH-macos-none"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
@ -18,6 +21,11 @@ fi
|
||||
|
||||
cd $ZIGDIR
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -27,7 +35,7 @@ export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
cmake .. \
|
||||
PATH="$HOME/local/bin:$PATH" cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
@ -39,12 +47,11 @@ cmake .. \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja
|
||||
|
||||
ninja install
|
||||
$HOME/local/bin/ninja install
|
||||
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-macos-sdk \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
--search-prefix "$PREFIX" \
|
||||
--test-timeout 2m
|
||||
--search-prefix "$PREFIX"
|
||||
|
||||
@ -3,10 +3,13 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
# Script assumes the presence of the following:
|
||||
# s3cmd
|
||||
|
||||
ZIGDIR="$PWD"
|
||||
TARGET="aarch64-macos-none"
|
||||
TARGET="$ARCH-macos-none"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
@ -18,6 +21,11 @@ fi
|
||||
|
||||
cd $ZIGDIR
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -27,7 +35,7 @@ export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
mkdir build-release
|
||||
cd build-release
|
||||
|
||||
cmake .. \
|
||||
PATH="$HOME/local/bin:$PATH" cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-release" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
@ -39,15 +47,14 @@ cmake .. \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja
|
||||
|
||||
ninja install
|
||||
$HOME/local/bin/ninja install
|
||||
|
||||
stage3-release/bin/zig build test docs \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-macos-sdk \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
--search-prefix "$PREFIX" \
|
||||
--test-timeout 2m
|
||||
--search-prefix "$PREFIX"
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
$TARGET = "aarch64-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
$TARGET = "$($Env:ARCH)-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
$MCPU = "baseline"
|
||||
$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
|
||||
$PREFIX_PATH = "$(Get-Location)\..\$ZIG_LLVM_CLANG_LLD_NAME"
|
||||
@ -22,6 +22,14 @@ function CheckLastExitCode {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the `zig build` command below which uses `git describe`.
|
||||
git fetch --tags
|
||||
|
||||
if ((git rev-parse --is-shallow-repository) -eq "true") {
|
||||
git fetch --unshallow # `git describe` won't work on a shallow repo
|
||||
}
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -58,8 +66,7 @@ Write-Output "Main test suite..."
|
||||
--search-prefix "$PREFIX_PATH" `
|
||||
-Dstatic-llvm `
|
||||
-Dskip-non-native `
|
||||
-Denable-symlinks-windows `
|
||||
--test-timeout 30m
|
||||
-Denable-symlinks-windows
|
||||
CheckLastExitCode
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="loongarch64-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.157+7fdd60df1"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 60129542144 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
|
||||
stage3-debug/bin/zig build \
|
||||
--prefix stage4-debug \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Dtarget=$TARGET \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-debug/bin/zig version)"
|
||||
|
||||
stage4-debug/bin/zig test ../test/behavior.zig
|
||||
@ -1,70 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="loongarch64-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.157+7fdd60df1"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-release
|
||||
cd build-release
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-release" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-release/bin/zig build test docs \
|
||||
--maxrss 60129542144 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
--prefix stage4-release \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Doptimize=ReleaseFast \
|
||||
-Dstrip \
|
||||
-Dtarget=$TARGET \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-release/bin/zig version)"
|
||||
|
||||
# diff returns an error code if the files differ.
|
||||
echo "If the following command fails, it means nondeterminism has been"
|
||||
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
|
||||
diff stage3-release/bin/zig stage4-release/bin/zig
|
||||
@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="riscv64-linux-musl"
|
||||
MCPU="spacemit_x60"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-riscv64-linux-musl-0.16.0-dev.104+689461e31"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/local/bin:$PATH"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-error-traces test-llvm-ir \
|
||||
--maxrss 68719476736 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dskip-single-threaded \
|
||||
-Dskip-compile-errors \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="riscv64-linux-musl"
|
||||
MCPU="spacemit_x60"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-riscv64-linux-musl-0.16.0-dev.104+689461e31"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/local/bin:$PATH"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-release
|
||||
cd build-release
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-release" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-error-traces test-llvm-ir \
|
||||
--maxrss 68719476736 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dskip-single-threaded \
|
||||
-Dskip-compile-errors \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
@ -1,65 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="s390x-linux-musl"
|
||||
MCPU="z15"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.1354+94e98bfe8"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 30064771072 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
|
||||
stage3-debug/bin/zig build \
|
||||
--prefix stage4-debug \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Dtarget=$TARGET \
|
||||
-Dcpu=$MCPU \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-debug/bin/zig version)"
|
||||
|
||||
stage4-debug/bin/zig test ../test/behavior.zig
|
||||
@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="s390x-linux-musl"
|
||||
MCPU="z15"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.1354+94e98bfe8"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-release
|
||||
cd build-release
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-release" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
|
||||
stage3-release/bin/zig build test docs \
|
||||
--maxrss 30064771072 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 4m
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
--prefix stage4-release \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Doptimize=ReleaseFast \
|
||||
-Dstrip \
|
||||
-Dtarget=$TARGET \
|
||||
-Dcpu=$MCPU \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-release/bin/zig version)"
|
||||
|
||||
# diff returns an error code if the files differ.
|
||||
echo "If the following command fails, it means nondeterminism has been"
|
||||
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
|
||||
diff stage3-release/bin/zig stage4-release/bin/zig
|
||||
@ -1,65 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="x86_64-freebsd-none"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.312+164c598cd"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 42949672960 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-linux \
|
||||
-Dskip-netbsd \
|
||||
-Dskip-windows \
|
||||
-Dskip-darwin \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 2m
|
||||
|
||||
stage3-debug/bin/zig build \
|
||||
--prefix stage4-debug \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Dtarget=$TARGET \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-debug/bin/zig version)"
|
||||
|
||||
stage4-debug/bin/zig test ../test/behavior.zig
|
||||
@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="x86_64-freebsd-none"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.312+164c598cd"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-release
|
||||
cd build-release
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-release" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja \
|
||||
-DCMAKE_C_LINKER_DEPFILE_SUPPORTED=FALSE \
|
||||
-DCMAKE_CXX_LINKER_DEPFILE_SUPPORTED=FALSE
|
||||
# https://github.com/ziglang/zig/issues/22213
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
stage3-release/bin/zig build test docs \
|
||||
--maxrss 42949672960 \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-linux \
|
||||
-Dskip-netbsd \
|
||||
-Dskip-windows \
|
||||
-Dskip-darwin \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
--test-timeout 2m
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
--prefix stage4-release \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Doptimize=ReleaseFast \
|
||||
-Dstrip \
|
||||
-Dtarget=$TARGET \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3-release/bin/zig version)"
|
||||
|
||||
# diff returns an error code if the files differ.
|
||||
echo "If the following command fails, it means nondeterminism has been"
|
||||
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
|
||||
diff stage3-release/bin/zig stage4-release/bin/zig
|
||||
@ -1,65 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires cmake ninja-build
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="x86_64-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/deps/wasmtime-v38.0.3-x86_64-linux:$HOME/deps/qemu-linux-x86_64-10.1.1.1/bin:$HOME/local/bin:$PATH"
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
mkdir build-debug-llvm
|
||||
cd build-debug-llvm
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX="stage3-debug" \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-DZIG_EXTRA_BUILD_ARGS="-Duse-llvm=true" \
|
||||
-GNinja
|
||||
|
||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||
# so that installation and testing do not get affected by them.
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
# simultaneously test building self-hosted without LLVM and with 32-bit arm
|
||||
stage3-debug/bin/zig build \
|
||||
-Dtarget=arm-linux-musleabihf \
|
||||
-Dno-lib
|
||||
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 21000000000 \
|
||||
-Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
|
||||
-fqemu \
|
||||
-fwasmtime \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-freebsd \
|
||||
-Dskip-netbsd \
|
||||
-Dskip-windows \
|
||||
-Dskip-darwin \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-superhtml \
|
||||
--test-timeout 12m
|
||||
@ -5,13 +5,19 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="x86_64-linux-musl"
|
||||
ARCH="$(uname -m)"
|
||||
TARGET="$ARCH-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/deps/wasmtime-v38.0.3-x86_64-linux:$HOME/deps/qemu-linux-x86_64-10.1.1.1/bin:$HOME/local/bin:$PATH"
|
||||
export PATH="$HOME/deps/wasmtime-v29.0.0-$ARCH-linux:$HOME/deps/qemu-linux-x86_64-9.2.0-rc1/bin:$HOME/local/bin:$PATH"
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
@ -19,6 +25,12 @@ export PATH="$HOME/deps/wasmtime-v38.0.3-x86_64-linux:$HOME/deps/qemu-linux-x86_
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
# Test building from source without LLVM.
|
||||
cc -o bootstrap bootstrap.c
|
||||
./bootstrap
|
||||
./zig2 build -Dno-lib
|
||||
./zig-out/bin/zig test test/behavior.zig
|
||||
|
||||
mkdir build-debug
|
||||
cd build-debug
|
||||
|
||||
@ -53,13 +65,39 @@ stage3-debug/bin/zig build test docs \
|
||||
-fqemu \
|
||||
-fwasmtime \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-freebsd \
|
||||
-Dskip-netbsd \
|
||||
-Dskip-windows \
|
||||
-Dskip-darwin \
|
||||
-Dskip-llvm \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-superhtml \
|
||||
--test-timeout 10m
|
||||
-Denable-superhtml
|
||||
|
||||
# Ensure that updating the wasm binary from this commit will result in a viable build.
|
||||
stage3-debug/bin/zig build update-zig1
|
||||
|
||||
mkdir ../build-new
|
||||
cd ../build-new
|
||||
|
||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON \
|
||||
-GNinja
|
||||
|
||||
unset CC
|
||||
unset CXX
|
||||
|
||||
ninja install
|
||||
|
||||
stage3/bin/zig test ../test/behavior.zig
|
||||
stage3/bin/zig build -p stage4 \
|
||||
-Dstatic-llvm \
|
||||
-Dtarget=native-native-musl \
|
||||
-Dno-lib \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib"
|
||||
stage4/bin/zig test ../test/behavior.zig
|
||||
|
||||
@ -5,13 +5,19 @@
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TARGET="x86_64-linux-musl"
|
||||
ARCH="$(uname -m)"
|
||||
TARGET="$ARCH-linux-musl"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/deps/$CACHE_BASENAME"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
export PATH="$HOME/deps/wasmtime-v38.0.3-x86_64-linux:$HOME/deps/qemu-linux-x86_64-10.1.1.1/bin:$HOME/local/bin:$PATH"
|
||||
export PATH="$HOME/deps/wasmtime-v29.0.0-$ARCH-linux:$HOME/deps/qemu-linux-x86_64-9.2.0-rc1/bin:$HOME/local/bin:$PATH"
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
@ -62,8 +68,7 @@ stage3-release/bin/zig build test docs \
|
||||
-Dtarget=native-native-musl \
|
||||
--search-prefix "$PREFIX" \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-superhtml \
|
||||
--test-timeout 12m
|
||||
-Denable-superhtml
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3-release/bin/zig build \
|
||||
|
||||
75
ci/x86_64-macos-release.sh
Executable file
75
ci/x86_64-macos-release.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
ZIGDIR="$PWD"
|
||||
TARGET="$ARCH-macos-none"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
JOBS="-j3"
|
||||
ZIG="$PREFIX/bin/zig"
|
||||
|
||||
if [ ! -d "$PREFIX" ]; then
|
||||
cd $HOME
|
||||
curl -L -O "https://ziglang.org/deps/$CACHE_BASENAME.tar.xz"
|
||||
tar xf "$CACHE_BASENAME.tar.xz"
|
||||
fi
|
||||
|
||||
cd $ZIGDIR
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git fetch --unshallow || true
|
||||
git fetch --tags
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
export ZIG_GLOBAL_CACHE_DIR="$PWD/zig-global-cache"
|
||||
export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
|
||||
|
||||
# Test building from source without LLVM.
|
||||
cc -o bootstrap bootstrap.c
|
||||
./bootstrap
|
||||
./zig2 build -Dno-lib
|
||||
./zig-out/bin/zig test test/behavior.zig
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH="$PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER="$ZIG;cc;-target;$TARGET;-mcpu=$MCPU" \
|
||||
-DCMAKE_CXX_COMPILER="$ZIG;c++;-target;$TARGET;-mcpu=$MCPU" \
|
||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||
-DZIG_TARGET_MCPU="$MCPU" \
|
||||
-DZIG_STATIC=ON \
|
||||
-DZIG_NO_LIB=ON
|
||||
|
||||
make $JOBS install
|
||||
|
||||
stage3/bin/zig build test docs \
|
||||
--zig-lib-dir "$PWD/../lib" \
|
||||
-Denable-macos-sdk \
|
||||
-Dstatic-llvm \
|
||||
-Dskip-non-native \
|
||||
--search-prefix "$PREFIX"
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
stage3/bin/zig build \
|
||||
--prefix stage4 \
|
||||
-Denable-llvm \
|
||||
-Dno-lib \
|
||||
-Doptimize=ReleaseFast \
|
||||
-Dstrip \
|
||||
-Dtarget=$TARGET \
|
||||
-Duse-zig-libcxx \
|
||||
-Dversion-string="$(stage3/bin/zig version)"
|
||||
|
||||
# diff returns an error code if the files differ.
|
||||
echo "If the following command fails, it means nondeterminism has been"
|
||||
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
|
||||
diff stage3/bin/zig stage4/bin/zig
|
||||
@ -1,5 +1,5 @@
|
||||
$TARGET = "x86_64-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
$TARGET = "$($Env:ARCH)-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
$MCPU = "baseline"
|
||||
$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
|
||||
$PREFIX_PATH = "$($Env:USERPROFILE)\$ZIG_LLVM_CLANG_LLD_NAME"
|
||||
@ -22,6 +22,14 @@ function CheckLastExitCode {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the `zig build` command below which uses `git describe`.
|
||||
git fetch --tags
|
||||
|
||||
if ((git rev-parse --is-shallow-repository) -eq "true") {
|
||||
git fetch --unshallow # `git describe` won't work on a shallow repo
|
||||
}
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -59,9 +67,7 @@ Write-Output "Main test suite..."
|
||||
-Dstatic-llvm `
|
||||
-Dskip-non-native `
|
||||
-Dskip-release `
|
||||
-Dskip-test-incremental `
|
||||
-Denable-symlinks-windows `
|
||||
--test-timeout 30m
|
||||
-Denable-symlinks-windows
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
|
||||
@ -96,7 +102,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build and run behavior tests with msvc..."
|
||||
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib ws2_32.lib
|
||||
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
|
||||
CheckLastExitCode
|
||||
|
||||
& .\test-x86_64-windows-msvc.exe
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
$TARGET = "x86_64-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.16.0-dev.104+689461e31"
|
||||
$TARGET = "$($Env:ARCH)-windows-gnu"
|
||||
$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.14.0-dev.1622+2ac543388"
|
||||
$MCPU = "baseline"
|
||||
$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
|
||||
$PREFIX_PATH = "$($Env:USERPROFILE)\$ZIG_LLVM_CLANG_LLD_NAME"
|
||||
@ -22,6 +22,14 @@ function CheckLastExitCode {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the `zig build` command below which uses `git describe`.
|
||||
git fetch --tags
|
||||
|
||||
if ((git rev-parse --is-shallow-repository) -eq "true") {
|
||||
git fetch --unshallow # `git describe` won't work on a shallow repo
|
||||
}
|
||||
|
||||
# Override the cache directories because they won't actually help other CI runs
|
||||
# which will be testing alternate versions of zig, and ultimately would just
|
||||
# fill up space on the hard drive for no reason.
|
||||
@ -58,9 +66,7 @@ Write-Output "Main test suite..."
|
||||
--search-prefix "$PREFIX_PATH" `
|
||||
-Dstatic-llvm `
|
||||
-Dskip-non-native `
|
||||
-Dskip-test-incremental `
|
||||
-Denable-symlinks-windows `
|
||||
--test-timeout 30m
|
||||
-Denable-symlinks-windows
|
||||
CheckLastExitCode
|
||||
|
||||
# Ensure that stage3 and stage4 are byte-for-byte identical.
|
||||
@ -114,7 +120,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build and run behavior tests with msvc..."
|
||||
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib ws2_32.lib
|
||||
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
|
||||
CheckLastExitCode
|
||||
|
||||
& .\test-x86_64-windows-msvc.exe
|
||||
|
||||
@ -17,10 +17,10 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
|
||||
if(${LLVM_LINK_MODE} STREQUAL "shared")
|
||||
find_library(CLANG_LIBRARIES
|
||||
NAMES
|
||||
libclang-cpp.so.21
|
||||
libclang-cpp.so.21.1
|
||||
clang-cpp-21.0
|
||||
clang-cpp210
|
||||
libclang-cpp.so.19
|
||||
libclang-cpp.so.19.1
|
||||
clang-cpp-19.0
|
||||
clang-cpp190
|
||||
clang-cpp
|
||||
NAMES_PER_DIR
|
||||
HINTS "${LLVM_LIBDIRS}"
|
||||
@ -60,6 +60,7 @@ else()
|
||||
FIND_AND_ADD_CLANG_LIB(clangBasic)
|
||||
FIND_AND_ADD_CLANG_LIB(clangEdit)
|
||||
FIND_AND_ADD_CLANG_LIB(clangLex)
|
||||
FIND_AND_ADD_CLANG_LIB(clangARCMigrate)
|
||||
FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend)
|
||||
FIND_AND_ADD_CLANG_LIB(clangRewrite)
|
||||
FIND_AND_ADD_CLANG_LIB(clangCrossTU)
|
||||
|
||||
@ -9,23 +9,23 @@
|
||||
find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h
|
||||
HINTS ${LLVM_INCLUDE_DIRS}
|
||||
PATHS
|
||||
/usr/lib/llvm-21/include
|
||||
/usr/local/llvm210/include
|
||||
/usr/local/llvm21/include
|
||||
/usr/local/opt/lld@21/include
|
||||
/opt/homebrew/opt/lld@21/include
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@21/include
|
||||
/usr/lib/llvm-19/include
|
||||
/usr/local/llvm190/include
|
||||
/usr/local/llvm19/include
|
||||
/usr/local/opt/lld@19/include
|
||||
/opt/homebrew/opt/lld@19/include
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@19/include
|
||||
/mingw64/include)
|
||||
|
||||
find_library(LLD_LIBRARY NAMES lld-21.0 lld210 lld NAMES_PER_DIR
|
||||
find_library(LLD_LIBRARY NAMES lld-19.0 lld190 lld NAMES_PER_DIR
|
||||
HINTS ${LLVM_LIBDIRS}
|
||||
PATHS
|
||||
/usr/lib/llvm-21/lib
|
||||
/usr/local/llvm210/lib
|
||||
/usr/local/llvm21/lib
|
||||
/usr/local/opt/lld@21/lib
|
||||
/opt/homebrew/opt/lld@21/lib
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@21/lib
|
||||
/usr/lib/llvm-19/lib
|
||||
/usr/local/llvm190/lib
|
||||
/usr/local/llvm19/lib
|
||||
/usr/local/opt/lld@19/lib
|
||||
/opt/homebrew/opt/lld@19/lib
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@19/lib
|
||||
)
|
||||
if(EXISTS ${LLD_LIBRARY})
|
||||
set(LLD_LIBRARIES ${LLD_LIBRARY})
|
||||
@ -36,12 +36,12 @@ else()
|
||||
HINTS ${LLVM_LIBDIRS}
|
||||
PATHS
|
||||
${LLD_LIBDIRS}
|
||||
/usr/lib/llvm-21/lib
|
||||
/usr/local/llvm210/lib
|
||||
/usr/local/llvm21/lib
|
||||
/usr/local/opt/lld@21/lib
|
||||
/opt/homebrew/opt/lld@21/lib
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@21/lib
|
||||
/usr/lib/llvm-19/lib
|
||||
/usr/local/llvm190/lib
|
||||
/usr/local/llvm19/lib
|
||||
/usr/local/opt/lld@19/lib
|
||||
/opt/homebrew/opt/lld@19/lib
|
||||
/home/linuxbrew/.linuxbrew/opt/lld@19/lib
|
||||
/mingw64/lib
|
||||
/c/msys64/mingw64/lib
|
||||
c:/msys64/mingw64/lib)
|
||||
|
||||
@ -17,12 +17,12 @@ if(ZIG_USE_LLVM_CONFIG)
|
||||
# terminate when the right LLVM version is not found.
|
||||
unset(LLVM_CONFIG_EXE CACHE)
|
||||
find_program(LLVM_CONFIG_EXE
|
||||
NAMES llvm-config-21 llvm-config-21.0 llvm-config210 llvm-config21 llvm-config NAMES_PER_DIR
|
||||
NAMES llvm-config-19 llvm-config-19.0 llvm-config190 llvm-config19 llvm-config NAMES_PER_DIR
|
||||
PATHS
|
||||
"/mingw64/bin"
|
||||
"/c/msys64/mingw64/bin"
|
||||
"c:/msys64/mingw64/bin"
|
||||
"C:/Libraries/llvm-21.0.0/bin")
|
||||
"C:/Libraries/llvm-19.0.0/bin")
|
||||
|
||||
if ("${LLVM_CONFIG_EXE}" STREQUAL "LLVM_CONFIG_EXE-NOTFOUND")
|
||||
if (NOT LLVM_CONFIG_ERROR_MESSAGES STREQUAL "")
|
||||
@ -40,9 +40,9 @@ if(ZIG_USE_LLVM_CONFIG)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
get_filename_component(LLVM_CONFIG_DIR "${LLVM_CONFIG_EXE}" DIRECTORY)
|
||||
if("${LLVM_CONFIG_VERSION}" VERSION_LESS 21 OR "${LLVM_CONFIG_VERSION}" VERSION_EQUAL 22 OR "${LLVM_CONFIG_VERSION}" VERSION_GREATER 22)
|
||||
if("${LLVM_CONFIG_VERSION}" VERSION_LESS 19 OR "${LLVM_CONFIG_VERSION}" VERSION_EQUAL 20 OR "${LLVM_CONFIG_VERSION}" VERSION_GREATER 20)
|
||||
# Save the error message, in case this is the last llvm-config we find
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "expected LLVM 21.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}")
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "expected LLVM 19.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}")
|
||||
|
||||
# Ignore this directory and try the search again
|
||||
list(APPEND CMAKE_IGNORE_PATH "${LLVM_CONFIG_DIR}")
|
||||
@ -66,9 +66,9 @@ if(ZIG_USE_LLVM_CONFIG)
|
||||
if (LLVM_CONFIG_ERROR)
|
||||
# Save the error message, in case this is the last llvm-config we find
|
||||
if (ZIG_SHARED_LLVM)
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 21.x found at ${LLVM_CONFIG_EXE} does not support linking as a shared library")
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 19.x found at ${LLVM_CONFIG_EXE} does not support linking as a shared library")
|
||||
else()
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 21.x found at ${LLVM_CONFIG_EXE} does not support linking as a static library")
|
||||
list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 19.x found at ${LLVM_CONFIG_EXE} does not support linking as a static library")
|
||||
endif()
|
||||
|
||||
# Ignore this directory and try the search again
|
||||
@ -83,7 +83,7 @@ if(ZIG_USE_LLVM_CONFIG)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE " " ";" LLVM_TARGETS_BUILT "${LLVM_TARGETS_BUILT_SPACES}")
|
||||
|
||||
set(ZIG_LLVM_REQUIRED_TARGETS "AArch64;AMDGPU;ARM;AVR;BPF;Hexagon;Lanai;LoongArch;Mips;MSP430;NVPTX;PowerPC;RISCV;SPIRV;Sparc;SystemZ;VE;WebAssembly;X86;XCore")
|
||||
set(ZIG_LLVM_REQUIRED_TARGETS "AArch64;AMDGPU;ARM;AVR;BPF;Hexagon;Lanai;Mips;MSP430;NVPTX;PowerPC;RISCV;Sparc;SystemZ;VE;WebAssembly;X86;XCore")
|
||||
|
||||
set(ZIG_LLVM_REQUIRED_TARGETS_ENABLED TRUE)
|
||||
foreach(TARGET_NAME IN LISTS ZIG_LLVM_REQUIRED_TARGETS)
|
||||
@ -197,10 +197,10 @@ else()
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMXRay)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMLibDriver)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDlltoolDriver)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMTelemetry)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMTextAPIBinaryReader)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCoverage)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMLineEditor)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSandboxIR)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMXCoreDisassembler)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMXCoreCodeGen)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMXCoreDesc)
|
||||
@ -227,10 +227,6 @@ else()
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSystemZCodeGen)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSystemZDesc)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSystemZInfo)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSPIRVCodeGen)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSPIRVDesc)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSPIRVInfo)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSPIRVAnalysis)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSparcDisassembler)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSparcAsmParser)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSparcCodeGen)
|
||||
@ -315,34 +311,32 @@ else()
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMOrcTargetProcess)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMOrcShared)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDWP)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDWARFCFIChecker)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoLogicalView)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoGSYM)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMOption)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMObjectYAML)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMObjCopy)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMMCA)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMMCDisassembler)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMLTO)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMPasses)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMHipStdPar)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCFGuard)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCoroutines)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMipo)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMVectorize)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMLinker)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMInstrumentation)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendOpenMP)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendOffloading)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendOpenACC)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendHLSL)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendDriver)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMExtensions)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMPasses)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMHipStdPar)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCoroutines)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCFGuard)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMipo)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMInstrumentation)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMVectorize)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMSandboxIR)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMLinker)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendOpenMP)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendDirective)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendAtomic)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFrontendOffloading)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMObjectYAML)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDWARFLinkerParallel)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDWARFLinkerClassic)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDWARFLinker)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCodeGenData)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMGlobalISel)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMMIRParser)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMAsmPrinter)
|
||||
@ -351,7 +345,6 @@ else()
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMTarget)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMObjCARCOpts)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCodeGenTypes)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCGData)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMIRPrinter)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMInterfaceStub)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFileCheck)
|
||||
@ -367,16 +360,14 @@ else()
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoBTF)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoPDB)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoMSF)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoCodeView)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoGSYM)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoDWARF)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoDWARFLowLevel)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMObject)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMTextAPI)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMMCParser)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMIRReader)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMAsmParser)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMMC)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoCodeView)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMBitReader)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMFuzzerCLI)
|
||||
FIND_AND_ADD_LLVM_LIB(LLVMCore)
|
||||
|
||||
@ -317,7 +317,6 @@
|
||||
<a href="https://ziglang.org/documentation/0.12.0/">0.12.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.13.0/">0.13.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.14.1/">0.14.1</a> |
|
||||
<a href="https://ziglang.org/documentation/0.15.2/">0.15.2</a> |
|
||||
master
|
||||
</nav>
|
||||
<nav aria-labelledby="table-of-contents">
|
||||
@ -375,8 +374,7 @@
|
||||
<p>
|
||||
Most of the time, it is more appropriate to write to stderr rather than stdout, and
|
||||
whether or not the message is successfully written to the stream is irrelevant.
|
||||
Also, formatted printing often comes in handy. For this common case,
|
||||
there is a simpler API:
|
||||
For this common case, there is a simpler API:
|
||||
</p>
|
||||
{#code|hello_again.zig#}
|
||||
|
||||
@ -421,7 +419,8 @@
|
||||
{#code|unattached_doc-comment.zig#}
|
||||
|
||||
<p>
|
||||
Doc comments can be interleaved with normal comments, which are ignored.
|
||||
Doc comments can be interleaved with normal comments. Currently, when producing
|
||||
the package documentation, normal comments are merged with doc comments.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|Top-Level Doc Comments#}
|
||||
@ -638,7 +637,7 @@
|
||||
{#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
|
||||
integer type is {#syntax#}65535{#endsyntax#}.
|
||||
</p>
|
||||
{#see_also|Integers|Floats|void|Errors|@Int#}
|
||||
{#see_also|Integers|Floats|void|Errors|@Type#}
|
||||
{#header_close#}
|
||||
{#header_open|Primitive Values#}
|
||||
<div class="table-wrapper">
|
||||
@ -778,7 +777,7 @@
|
||||
value. Using this value would be a bug. The value will be unused, or overwritten before being used."
|
||||
</p>
|
||||
<p>
|
||||
In {#link|Debug#} and {#link|ReleaseSafe#} mode, Zig writes {#syntax#}0xaa{#endsyntax#} bytes to undefined memory. This is to catch
|
||||
In {#link|Debug#} mode, Zig writes {#syntax#}0xaa{#endsyntax#} bytes to undefined memory. This is to catch
|
||||
bugs early, and to help detect use of undefined memory in a debugger. However, this behavior is only an
|
||||
implementation feature, not a language semantic, so it is not guaranteed to be observable to code.
|
||||
</p>
|
||||
@ -1650,7 +1649,6 @@ unwrapped == 1234{#endsyntax#}</pre>
|
||||
<li>{#link|Floats#}</li>
|
||||
<li>{#link|bool|Primitive Types#}</li>
|
||||
<li>{#link|type|Primitive Types#}</li>
|
||||
<li>{#link|packed struct#}</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
@ -1927,10 +1925,8 @@ or
|
||||
Vector types are created with the builtin function {#link|@Vector#}.
|
||||
</p>
|
||||
<p>
|
||||
Vectors generally support the same builtin operators as their underlying base types.
|
||||
The only exception to this is the keywords `and` and `or` on vectors of bools, since
|
||||
these operators affect control flow, which is not allowed for vectors.
|
||||
All other operations are performed element-wise, and return a vector of the same length
|
||||
Vectors support the same builtin operators as their underlying base types.
|
||||
These operations are performed element-wise, and return a vector of the same length
|
||||
as the input vectors. This includes:
|
||||
</p>
|
||||
<ul>
|
||||
@ -1940,7 +1936,6 @@ or
|
||||
<li>Bitwise operators ({#syntax#}>>{#endsyntax#}, {#syntax#}<<{#endsyntax#}, {#syntax#}&{#endsyntax#},
|
||||
{#syntax#}|{#endsyntax#}, {#syntax#}~{#endsyntax#}, etc.)</li>
|
||||
<li>Comparison operators ({#syntax#}<{#endsyntax#}, {#syntax#}>{#endsyntax#}, {#syntax#}=={#endsyntax#}, etc.)</li>
|
||||
<li>Boolean not ({#syntax#}!{#endsyntax#})</li>
|
||||
</ul>
|
||||
<p>
|
||||
It is prohibited to use a math operator on a mixture of scalars (individual numbers)
|
||||
@ -1968,14 +1963,6 @@ or
|
||||
</p>
|
||||
{#see_also|@splat|@shuffle|@select|@reduce#}
|
||||
|
||||
{#header_open|Relationship with Arrays#}
|
||||
<p>Vectors and {#link|Arrays#} each have a well-defined <strong>bit layout</strong>
|
||||
and therefore support {#link|@bitCast#} between each other. {#link|Type Coercion#} implicitly peforms
|
||||
{#syntax#}@bitCast{#endsyntax#}.</p>
|
||||
<p>Arrays have well-defined byte layout, but vectors do not, making {#link|@ptrCast#} between
|
||||
them {#link|Illegal Behavior#}.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Destructuring Vectors#}
|
||||
<p>
|
||||
Vectors can be destructured:
|
||||
@ -2237,24 +2224,20 @@ or
|
||||
|
||||
{#header_open|packed struct#}
|
||||
<p>
|
||||
{#syntax#}packed{#endsyntax#} structs, like {#syntax#}enum{#endsyntax#}, are based on the concept
|
||||
of interpreting integers differently. All packed structs have a <strong>backing integer</strong>,
|
||||
which is implicitly determined by the total bit count of fields, or explicitly specified.
|
||||
Packed structs have well-defined memory layout - exactly the same ABI as their backing integer.
|
||||
</p>
|
||||
<p>
|
||||
Each field of a packed struct is interpreted as a logical sequence of bits, arranged from
|
||||
least to most significant. Allowed field types:
|
||||
Unlike normal structs, {#syntax#}packed{#endsyntax#} structs have guaranteed in-memory layout:
|
||||
</p>
|
||||
<ul>
|
||||
<li>An {#link|integer|Integers#} field uses exactly as many bits as its
|
||||
bit width. For example, a {#syntax#}u5{#endsyntax#} will use 5 bits of
|
||||
the backing integer.</li>
|
||||
<li>A {#link|bool|Primitive Types#} field uses exactly 1 bit.</li>
|
||||
<li>Fields remain in the order declared, least to most significant.</li>
|
||||
<li>There is no padding between fields.</li>
|
||||
<li>Zig supports arbitrary width {#link|Integers#} and although normally, integers with fewer
|
||||
than 8 bits will still use 1 byte of memory, in packed structs, they use
|
||||
exactly their bit width.
|
||||
</li>
|
||||
<li>{#syntax#}bool{#endsyntax#} fields use exactly 1 bit.</li>
|
||||
<li>An {#link|enum#} field uses exactly the bit width of its integer tag type.</li>
|
||||
<li>A {#link|packed union#} field uses exactly the bit width of the union field with
|
||||
the largest bit width.</li>
|
||||
<li>A {#syntax#}packed struct{#endsyntax#} field uses the bits of its backing integer.</li>
|
||||
<li>Packed structs support equality operators.</li>
|
||||
</ul>
|
||||
<p>
|
||||
This means that a {#syntax#}packed struct{#endsyntax#} can participate
|
||||
@ -2262,11 +2245,10 @@ or
|
||||
This even works at {#link|comptime#}:
|
||||
</p>
|
||||
{#code|test_packed_structs.zig#}
|
||||
|
||||
<p>
|
||||
The backing integer can be inferred or explicitly provided. When
|
||||
inferred, it will be unsigned. When explicitly provided, its bit width
|
||||
will be enforced at compile time to exactly match the total bit width of
|
||||
the fields:
|
||||
The backing integer is inferred from the fields' total bit width.
|
||||
Optionally, it can be explicitly provided and enforced at compile time:
|
||||
</p>
|
||||
{#code|test_missized_packed_struct.zig#}
|
||||
|
||||
@ -2307,19 +2289,19 @@ or
|
||||
{#code|test_aligned_struct_fields.zig#}
|
||||
|
||||
<p>
|
||||
Equating packed structs results in a comparison of the backing integer,
|
||||
and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}.
|
||||
Equating packed structs results in a comparison of the backing integer,
|
||||
and only works for the `==` and `!=` operators.
|
||||
</p>
|
||||
{#code|test_packed_struct_equality.zig#}
|
||||
|
||||
<p>
|
||||
Field access and assignment can be understood as shorthand for bitshifts
|
||||
on the backing integer. These operations are not {#link|atomic|Atomics#},
|
||||
so beware using field access syntax when combined with memory-mapped
|
||||
input-output (MMIO). Instead of field access on {#link|volatile#} {#link|Pointers#},
|
||||
construct a fully-formed new value first, then write that value to the volatile pointer.
|
||||
Using packed structs with {#link|volatile#} is problematic, and may be a compile error in the future.
|
||||
For details on this subscribe to
|
||||
<a href="https://github.com/ziglang/zig/issues/1761">this issue</a>.
|
||||
TODO update these docs with a recommendation on how to use packed structs with MMIO
|
||||
(the use case for volatile packed structs) once this issue is resolved.
|
||||
Don't worry, there will be a good solution for this use case in zig.
|
||||
</p>
|
||||
{#code|packed_struct_mmio.zig#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Struct Naming#}
|
||||
@ -2477,13 +2459,6 @@ or
|
||||
</p>
|
||||
{#code|test_union_method.zig#}
|
||||
|
||||
<p>
|
||||
Unions with inferred enum tag types can also assign ordinal values to their inferred tag.
|
||||
This requires the tag to specify an explicit integer type.
|
||||
{#link|@intFromEnum#} can be used to access the ordinal value corresponding to the active field.
|
||||
</p>
|
||||
{#code|test_tagged_union_with_tag_values.zig#}
|
||||
|
||||
<p>
|
||||
{#link|@tagName#} can be used to return a {#link|comptime#}
|
||||
{#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
|
||||
@ -2503,7 +2478,6 @@ or
|
||||
{#header_open|packed union#}
|
||||
<p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
|
||||
to be in a {#link|packed struct#}.</p>
|
||||
<p>All fields in a packed union must have the same {#link|@bitSizeOf#}.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Anonymous Union Literals#}
|
||||
@ -3024,7 +2998,7 @@ or
|
||||
{#syntax#}catch{#endsyntax#} after performing some logic, you
|
||||
can combine {#syntax#}catch{#endsyntax#} with named {#link|Blocks#}:
|
||||
</p>
|
||||
{#code|handle_error_with_catch_block.zig#}
|
||||
{#code|handle_error_with_catch_block.zig.zig#}
|
||||
|
||||
{#header_close#}
|
||||
{#header_open|try#}
|
||||
@ -3231,7 +3205,7 @@ fn createFoo(param: i32) !Foo {
|
||||
to increase their development pace.
|
||||
</p>
|
||||
<p>
|
||||
Error Return Traces are enabled by default in {#link|Debug#} builds and disabled by default in {#link|ReleaseFast#}, {#link|ReleaseSafe#} and {#link|ReleaseSmall#} builds.
|
||||
Error Return Traces are enabled by default in {#link|Debug#} and {#link|ReleaseSafe#} builds and disabled by default in {#link|ReleaseFast#} and {#link|ReleaseSmall#} builds.
|
||||
</p>
|
||||
<p>
|
||||
There are a few ways to activate this error return tracing feature:
|
||||
@ -3723,9 +3697,9 @@ void do_a_thing(struct Foo *foo) {
|
||||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}@FieldType(T, "a"){#endsyntax#}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
|
||||
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
|
||||
<td>-</td>
|
||||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Signedness{#endsyntax#}, {#syntax#}y{#endsyntax#} is a {#syntax#}u16{#endsyntax#}</td>
|
||||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Type{#endsyntax#}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
|
||||
@ -3839,9 +3813,9 @@ void do_a_thing(struct Foo *foo) {
|
||||
<td>{#syntax#}x{#endsyntax#} has no result location (typed initializers do not propagate result locations)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
|
||||
<td>-</td>
|
||||
<td>{#syntax#}x{#endsyntax#} and {#syntax#}y{#endsyntax#} do not have result locations</td>
|
||||
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
|
||||
<td>{#syntax#}ptr{#endsyntax#}</td>
|
||||
<td>{#syntax#}x{#endsyntax#} has no result location</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
|
||||
@ -3859,6 +3833,37 @@ void do_a_thing(struct Foo *foo) {
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|usingnamespace#}
|
||||
<p>
|
||||
{#syntax#}usingnamespace{#endsyntax#} is a declaration that mixes all the public
|
||||
declarations of the operand, which must be a {#link|struct#}, {#link|union#}, {#link|enum#},
|
||||
or {#link|opaque#}, into the namespace:
|
||||
</p>
|
||||
{#code|test_usingnamespace.zig#}
|
||||
|
||||
<p>
|
||||
{#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public
|
||||
API of a file or package. For example, one might have <code class="file">c.zig</code> with all of the
|
||||
{#link|C imports|Import from C Header File#}:
|
||||
</p>
|
||||
{#syntax_block|zig|c.zig#}
|
||||
pub usingnamespace @cImport({
|
||||
@cInclude("epoxy/gl.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
@cDefine("STBI_ONLY_PNG", "");
|
||||
@cDefine("STBI_NO_STDIO", "");
|
||||
@cInclude("stb_image.h");
|
||||
});
|
||||
{#end_syntax_block#}
|
||||
<p>
|
||||
The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the
|
||||
{#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations
|
||||
{#syntax#}pub{#endsyntax#}. This can be used to forward declarations, giving precise control
|
||||
over what declarations a given file exposes.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
|
||||
{#header_open|comptime#}
|
||||
<p>
|
||||
Zig places importance on the concept of whether an expression is known at compile-time.
|
||||
@ -4265,9 +4270,16 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Async Functions#}
|
||||
<p>Async functions regressed with the release of 0.11.0. The current plan is to
|
||||
reintroduce them as a lower level primitive that powers I/O implementations.</p>
|
||||
<p>Tracking issue: <a href="https://github.com/ziglang/zig/issues/23446">Proposal: stackless coroutines as low-level primitives</a></p>
|
||||
<p>Async functions regressed with the release of 0.11.0. Their future in
|
||||
the Zig language is unclear due to multiple unsolved problems:</p>
|
||||
<ul>
|
||||
<li>LLVM's lack of ability to optimize them.</li>
|
||||
<li>Third-party debuggers' lack of ability to debug them.</li>
|
||||
<li><a href="https://github.com/ziglang/zig/issues/5913">The cancellation problem</a>.</li>
|
||||
<li>Async function pointers preventing the stack size from being known.</li>
|
||||
</ul>
|
||||
<p>These problems are surmountable, but it will take time. The Zig team
|
||||
is currently focused on other priorities.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Builtin Functions|2col#}
|
||||
@ -4335,7 +4347,7 @@ comptime {
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer, an enum, or a packed struct.
|
||||
an integer or an enum.
|
||||
</p>
|
||||
<p>{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.</p>
|
||||
{#see_also|@atomicStore|@atomicRmw||@cmpxchgWeak|@cmpxchgStrong#}
|
||||
@ -4349,7 +4361,7 @@ comptime {
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer, an enum, or a packed struct.
|
||||
an integer or an enum.
|
||||
</p>
|
||||
<p>{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.</p>
|
||||
<p>{#syntax#}AtomicRmwOp{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicRmwOp{#endsyntax#}.</p>
|
||||
@ -4363,7 +4375,7 @@ comptime {
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer, an enum, or a packed struct.
|
||||
an integer or an enum.
|
||||
</p>
|
||||
<p>{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.</p>
|
||||
{#see_also|@atomicLoad|@atomicRmw|@cmpxchgWeak|@cmpxchgStrong#}
|
||||
@ -4592,8 +4604,8 @@ comptime {
|
||||
more efficiently in machine instructions.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#},
|
||||
an integer, an enum, or a packed struct.
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer or an enum.
|
||||
</p>
|
||||
<p>{#syntax#}@typeInfo(@TypeOf(ptr)).pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
<p>{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.</p>
|
||||
@ -4624,8 +4636,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#},
|
||||
an integer, an enum, or a packed struct.
|
||||
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer or an enum.
|
||||
</p>
|
||||
<p>{#syntax#}@typeInfo(@TypeOf(ptr)).pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
<p>{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.</p>
|
||||
@ -4856,7 +4868,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
<p>
|
||||
This builtin can be called from a {#link|comptime#} block to conditionally export symbols.
|
||||
When <code>ptr</code> points to a function with the C calling convention and
|
||||
{#syntax#}options.linkage{#endsyntax#} is {#syntax#}.strong{#endsyntax#}, this is equivalent to
|
||||
{#syntax#}options.linkage{#endsyntax#} is {#syntax#}.Strong{#endsyntax#}, this is equivalent to
|
||||
the {#syntax#}export{#endsyntax#} keyword used on a function:
|
||||
</p>
|
||||
{#code|export_builtin.zig#}
|
||||
@ -4896,8 +4908,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#header_open|@fieldParentPtr#}
|
||||
<pre>{#syntax#}@fieldParentPtr(comptime field_name: []const u8, field_ptr: *T) anytype{#endsyntax#}</pre>
|
||||
<p>
|
||||
Given a pointer to a struct or union field, returns a pointer to the struct or union containing that field.
|
||||
The return type (pointer to the parent struct or union in question) is the inferred result type.
|
||||
Given a pointer to a struct field, returns a pointer to the struct containing that field.
|
||||
The return type (and struct in question) is the inferred result type.
|
||||
</p>
|
||||
<p>
|
||||
If {#syntax#}field_ptr{#endsyntax#} does not point to the {#syntax#}field_name{#endsyntax#} field of an instance of
|
||||
@ -4968,25 +4980,34 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@import#}
|
||||
<pre>{#syntax#}@import(comptime target: []const u8) anytype{#endsyntax#}</pre>
|
||||
<p>Imports the file at {#syntax#}target{#endsyntax#}, adding it to the compilation if it is not already
|
||||
added. {#syntax#}target{#endsyntax#} is either a relative path to another file from the file containing
|
||||
the {#syntax#}@import{#endsyntax#} call, or it is the name of a {#link|module|Compilation Model#}, with
|
||||
the import referring to the root source file of that module. Either way, the file path must end in
|
||||
either <code>.zig</code> (for a Zig source file) or <code>.zon</code> (for a ZON data file).</p>
|
||||
<p>If {#syntax#}target{#endsyntax#} refers to a Zig source file, then {#syntax#}@import{#endsyntax#} returns
|
||||
that file's {#link|corresponding struct type|Source File Structs#}, essentially as if the builtin call was
|
||||
replaced by {#syntax#}struct { FILE_CONTENTS }{#endsyntax#}. The return type is {#syntax#}type{#endsyntax#}.</p>
|
||||
<p>If {#syntax#}target{#endsyntax#} refers to a ZON file, then {#syntax#}@import{#endsyntax#} returns the value
|
||||
of the literal in the file. If there is an inferred {#link|result type|Result Types#}, then the return type
|
||||
is that type, and the ZON literal is interpreted as that type ({#link|Result Types#} are propagated through
|
||||
the ZON expression). Otherwise, the return type is the type of the equivalent Zig expression, essentially as
|
||||
if the builtin call was replaced by the ZON file contents.</p>
|
||||
<p>The following modules are always available for import:</p>
|
||||
<pre>{#syntax#}@import(comptime path: []const u8) type{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function finds a zig file corresponding to {#syntax#}path{#endsyntax#} and adds it to the build,
|
||||
if it is not already added.
|
||||
</p>
|
||||
<p>
|
||||
Zig source files are implicitly structs, with a name equal to the file's basename with the extension
|
||||
truncated. {#syntax#}@import{#endsyntax#} returns the struct type corresponding to the file.
|
||||
</p>
|
||||
<p>
|
||||
Declarations which have the {#syntax#}pub{#endsyntax#} keyword may be referenced from a different
|
||||
source file than the one they are declared in.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}path{#endsyntax#} can be a relative path or it can be the name of a package.
|
||||
If it is a relative path, it is relative to the file that contains the {#syntax#}@import{#endsyntax#}
|
||||
function call.
|
||||
</p>
|
||||
<p>
|
||||
The following packages are always available:
|
||||
</p>
|
||||
<ul>
|
||||
<li>{#syntax#}@import("std"){#endsyntax#} - Zig Standard Library</li>
|
||||
<li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information. The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.</li>
|
||||
<li>{#syntax#}@import("root"){#endsyntax#} - Alias for the root module. In typical project structures, this means it refers back to <code>src/main.zig</code>.
|
||||
<li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information
|
||||
The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.
|
||||
</li>
|
||||
<li>{#syntax#}@import("root"){#endsyntax#} - Root source file
|
||||
This is usually <code>src/main.zig</code> but depends on what file is built.
|
||||
</li>
|
||||
</ul>
|
||||
{#see_also|Compile Variables|@embedFile#}
|
||||
@ -5122,23 +5143,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#syntax#}std.crypto.secureZero{#endsyntax#}</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@memmove#}
|
||||
<pre>{#syntax#}@memmove(dest, source) void{#endsyntax#}</pre>
|
||||
<p>This function copies bytes from one region of memory to another, but unlike
|
||||
{#link|@memcpy#} the regions may overlap.</p>
|
||||
<p>{#syntax#}dest{#endsyntax#} must be a mutable slice, a mutable pointer to an array, or
|
||||
a mutable many-item {#link|pointer|Pointers#}. It may have any
|
||||
alignment, and it may have any element type.</p>
|
||||
<p>{#syntax#}source{#endsyntax#} must be a slice, a pointer to
|
||||
an array, or a many-item {#link|pointer|Pointers#}. It may
|
||||
have any alignment, and it may have any element type.</p>
|
||||
<p>The {#syntax#}source{#endsyntax#} element type must have the same in-memory
|
||||
representation as the {#syntax#}dest{#endsyntax#} element type.</p>
|
||||
<p>Similar to {#link|for#} loops, at least one of {#syntax#}source{#endsyntax#} and
|
||||
{#syntax#}dest{#endsyntax#} must provide a length, and if two lengths are provided,
|
||||
they must be equal.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@min#}
|
||||
<pre>{#syntax#}@min(...) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
@ -5186,7 +5190,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
<pre>{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
Modulus division. For unsigned integers this is the same as
|
||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#}, otherwise the
|
||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the
|
||||
operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
|
||||
</p>
|
||||
<ul>
|
||||
@ -5291,7 +5295,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
<pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
Remainder division. For unsigned integers this is the same as
|
||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#}, otherwise the
|
||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the
|
||||
operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
|
||||
</p>
|
||||
<ul>
|
||||
@ -5494,9 +5498,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#header_open|@splat#}
|
||||
<pre>{#syntax#}@splat(scalar: anytype) anytype{#endsyntax#}</pre>
|
||||
<p>
|
||||
Produces an array or vector where each element is the value
|
||||
{#syntax#}scalar{#endsyntax#}. The return type and thus the length of the
|
||||
vector is inferred.
|
||||
Produces a vector where each element is the value {#syntax#}scalar{#endsyntax#}.
|
||||
The return type and thus the length of the vector is inferred.
|
||||
</p>
|
||||
{#code|test_splat_builtin.zig#}
|
||||
|
||||
@ -5755,75 +5758,41 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@EnumLiteral#}
|
||||
<pre>{#syntax#}@EnumLiteral() type{#endsyntax#}</pre>
|
||||
<p>Returns the comptime-only "enum literal" type. This is the type of uncoerced {#link|Enum Literals#}. Values of this type can coerce to any {#link|enum#} with a matching field.</p>
|
||||
{#header_open|@Type#}
|
||||
<pre>{#syntax#}@Type(comptime info: std.builtin.Type) type{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function is the inverse of {#link|@typeInfo#}. It reifies type information
|
||||
into a {#syntax#}type{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
It is available for the following types:
|
||||
</p>
|
||||
<ul>
|
||||
<li>{#syntax#}type{#endsyntax#}</li>
|
||||
<li>{#syntax#}noreturn{#endsyntax#}</li>
|
||||
<li>{#syntax#}void{#endsyntax#}</li>
|
||||
<li>{#syntax#}bool{#endsyntax#}</li>
|
||||
<li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li>
|
||||
<li>{#link|Floats#}</li>
|
||||
<li>{#link|Pointers#}</li>
|
||||
<li>{#syntax#}comptime_int{#endsyntax#}</li>
|
||||
<li>{#syntax#}comptime_float{#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(null){#endsyntax#}</li>
|
||||
<li>{#link|Arrays#}</li>
|
||||
<li>{#link|Optionals#}</li>
|
||||
<li>{#link|Error Set Type#}</li>
|
||||
<li>{#link|Error Union Type#}</li>
|
||||
<li>{#link|Vectors#}</li>
|
||||
<li>{#link|opaque#}</li>
|
||||
<li>{#syntax#}anyframe{#endsyntax#}</li>
|
||||
<li>{#link|struct#}</li>
|
||||
<li>{#link|enum#}</li>
|
||||
<li>{#link|Enum Literals#}</li>
|
||||
<li>{#link|union#}</li>
|
||||
<li>{#link|Functions#}</li>
|
||||
</ul>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Int#}
|
||||
<pre>{#syntax#}@Int(comptime signedness: std.builtin.Signedness, comptime bits: u16) type{#endsyntax#}</pre>
|
||||
<p>Returns an integer type with the given signedness and bit width.</p>
|
||||
<p>For instance, {#syntax#}@Int(.unsigned, 18){#endsyntax#} returns the type {#syntax#}u18{#endsyntax#}.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Tuple#}
|
||||
<pre>{#syntax#}@Tuple(comptime field_types: []const type) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|tuple|Tuples#} type with the given field types.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Pointer#}
|
||||
<pre>{#syntax#}@Pointer(
|
||||
comptime size: std.builtin.Type.Pointer.Size,
|
||||
comptime attrs: std.builtin.Type.Pointer.Attributes,
|
||||
comptime Element: type,
|
||||
comptime sentinel: ?Element,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Fn#}
|
||||
<pre>{#syntax#}@Fn(
|
||||
comptime param_types: []const type,
|
||||
comptime param_attrs: *const [param_types.len]std.builtin.Type.Fn.Param.Attributes,
|
||||
comptime ReturnType: type,
|
||||
comptime attrs: std.builtin.Type.Fn.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|function|Functions#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Struct#}
|
||||
<pre>{#syntax#}@Struct(
|
||||
comptime layout: std.builtin.Type.ContainerLayout,
|
||||
comptime BackingInt: ?type,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_types: *const [field_names.len]type,
|
||||
comptime field_attrs: *const [field_names.len]std.builtin.Type.StructField.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|struct#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Union#}
|
||||
<pre>{#syntax#}@Union(
|
||||
comptime layout: std.builtin.Type.ContainerLayout,
|
||||
/// Either the integer tag type, or the integer backing type, depending on `layout`.
|
||||
comptime ArgType: ?type,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_types: *const [field_names.len]type,
|
||||
comptime field_attrs: *const [field_names.len]std.builtin.Type.UnionField.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|union#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Enum#}
|
||||
<pre>{#syntax#}@Enum(
|
||||
comptime TagInt: type,
|
||||
comptime mode: std.builtin.Type.Enum.Mode,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_values: *const [field_names.len]TagInt,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns an {#link|enum#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@typeInfo#}
|
||||
<pre>{#syntax#}@typeInfo(comptime T: type) std.builtin.Type{#endsyntax#}</pre>
|
||||
<p>
|
||||
@ -6127,7 +6096,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#header_close#}
|
||||
{#header_open|Exact Left Shift Overflow#}
|
||||
<p>At compile-time:</p>
|
||||
{#code|test_comptime_shlExact_overflow.zig#}
|
||||
{#code|test_comptime_shlExact_overwlow.zig#}
|
||||
|
||||
<p>At runtime:</p>
|
||||
{#code|runtime_shlExact_overflow.zig#}
|
||||
@ -6291,8 +6260,9 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
C has a default allocator - <code>malloc</code>, <code>realloc</code>, and <code>free</code>.
|
||||
When linking against libc, Zig exposes this allocator with {#syntax#}std.heap.c_allocator{#endsyntax#}.
|
||||
However, by convention, there is no default allocator in Zig. Instead, functions which need to
|
||||
allocate accept an {#syntax#}Allocator{#endsyntax#} parameter. Likewise, some data structures
|
||||
accept an {#syntax#}Allocator{#endsyntax#} parameter in their initialization functions:
|
||||
allocate accept an {#syntax#}Allocator{#endsyntax#} parameter. Likewise, data structures such as
|
||||
{#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}Allocator{#endsyntax#} parameter in
|
||||
their initialization functions:
|
||||
</p>
|
||||
{#code|test_allocator.zig#}
|
||||
|
||||
@ -6319,6 +6289,10 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
</li>
|
||||
<li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
|
||||
the right choice, at least for your main allocator.</li>
|
||||
<li>
|
||||
Need to use the same allocator in multiple threads? Use one of your choice
|
||||
wrapped around {#syntax#}std.heap.ThreadSafeAllocator{#endsyntax#}
|
||||
</li>
|
||||
<li>
|
||||
Is the maximum number of bytes that you will need bounded by a number known at
|
||||
{#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#}.
|
||||
@ -6328,7 +6302,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
cyclical pattern (such as a video game main loop, or a web server request handler),
|
||||
such that it would make sense to free everything at once at the end?
|
||||
In this case, it is recommended to follow this pattern:
|
||||
{#code|cli_allocation.zig#}
|
||||
{#code|cli_allocation.zig#}
|
||||
|
||||
When using this kind of allocator, there is no need to free anything manually. Everything
|
||||
gets freed at once with the call to {#syntax#}arena.deinit(){#endsyntax#}.
|
||||
@ -6351,18 +6325,14 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
</li>
|
||||
<li>
|
||||
Finally, if none of the above apply, you need a general purpose allocator.
|
||||
If you are in Debug mode, {#syntax#}std.heap.DebugAllocator{#endsyntax#} is available as a
|
||||
function that takes a {#link|comptime#} {#link|struct#} of configuration options and returns a type.
|
||||
Generally, you will set up exactly one in your main function, and
|
||||
then pass it or sub-allocators around to various parts of your
|
||||
Zig's general purpose allocator is available as a function that takes a {#link|comptime#}
|
||||
{#link|struct#} of configuration options and returns a type.
|
||||
Generally, you will set up one {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#} in
|
||||
your main function, and then pass it or sub-allocators around to various parts of your
|
||||
application.
|
||||
</li>
|
||||
<li>
|
||||
If you are compiling in ReleaseFast mode, {#syntax#}std.heap.smp_allocator{#endsyntax#} is
|
||||
a solid choice for a general purpose allocator.
|
||||
</li>
|
||||
<li>
|
||||
You can also consider implementing an allocator.
|
||||
You can also consider {#link|Implementing an Allocator#}.
|
||||
</li>
|
||||
</ol>
|
||||
{#header_close#}
|
||||
@ -6397,6 +6367,17 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
<p>TODO: thread local variables</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Implementing an Allocator#}
|
||||
<p>Zig programmers can implement their own allocators by fulfilling the Allocator interface.
|
||||
In order to do this one must read carefully the documentation comments in std/mem.zig and
|
||||
then supply a {#syntax#}allocFn{#endsyntax#} and a {#syntax#}resizeFn{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
There are many example allocators to look at for inspiration. Look at std/heap.zig and
|
||||
{#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#}.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Heap Allocation Failure#}
|
||||
<p>
|
||||
Many programming languages choose to handle the possibility of heap allocation failure by
|
||||
@ -6544,7 +6525,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
</p>
|
||||
<ul>
|
||||
<li>If a call to {#syntax#}@import{#endsyntax#} is analyzed, the file being imported is analyzed.</li>
|
||||
<li>If a type (including a file) is analyzed, all {#syntax#}comptime{#endsyntax#} and {#syntax#}export{#endsyntax#} declarations within it are analyzed.</li>
|
||||
<li>If a type (including a file) is analyzed, all {#syntax#}comptime{#endsyntax#}, {#syntax#}usingnamespace{#endsyntax#}, and {#syntax#}export{#endsyntax#} declarations within it are analyzed.</li>
|
||||
<li>If a type (including a file) is analyzed, and the compilation is for a {#link|test|Zig Test#}, and the module the type is within is the root module of the compilation, then all {#syntax#}test{#endsyntax#} declarations within it are also analyzed.</li>
|
||||
<li>If a reference to a named declaration (i.e. a usage of it) is analyzed, the declaration being referenced is analyzed. Declarations are order-independent, so this reference may be above or below the declaration being referenced, or even in another file entirely.</li>
|
||||
</ul>
|
||||
@ -7138,12 +7119,10 @@ coding style.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
If {#syntax#}x{#endsyntax#} is a {#syntax#}struct{#endsyntax#} with 0 fields and is never meant to be instantiated
|
||||
then {#syntax#}x{#endsyntax#} is considered to be a "namespace" and should be {#syntax#}snake_case{#endsyntax#}.
|
||||
</li>
|
||||
<li>
|
||||
If {#syntax#}x{#endsyntax#} is a {#syntax#}type{#endsyntax#} or {#syntax#}type{#endsyntax#} alias
|
||||
then {#syntax#}x{#endsyntax#} should be {#syntax#}TitleCase{#endsyntax#}.
|
||||
If {#syntax#}x{#endsyntax#} is a {#syntax#}type{#endsyntax#}
|
||||
then {#syntax#}x{#endsyntax#} should be {#syntax#}TitleCase{#endsyntax#}, unless it
|
||||
is a {#syntax#}struct{#endsyntax#} with 0 fields and is never meant to be instantiated,
|
||||
in which case it is considered to be a "namespace" and uses {#syntax#}snake_case{#endsyntax#}.
|
||||
</li>
|
||||
<li>
|
||||
If {#syntax#}x{#endsyntax#} is callable, and {#syntax#}x{#endsyntax#}'s return type is
|
||||
@ -7182,7 +7161,8 @@ const namespace_name = @import("dir_name/file_name.zig");
|
||||
const TypeName = @import("dir_name/TypeName.zig");
|
||||
var global_var: i32 = undefined;
|
||||
const const_name = 42;
|
||||
const PrimitiveTypeAlias = f32;
|
||||
const primitive_type_alias = f32;
|
||||
const string_alias = []u8;
|
||||
|
||||
const StructName = struct {
|
||||
field: i32,
|
||||
@ -7365,6 +7345,29 @@ fn readU32Be() u32 {}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<pre>{#syntax#}async{#endsyntax#}</pre>
|
||||
</th>
|
||||
<td>
|
||||
{#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.
|
||||
<ul>
|
||||
<li>See also {#link|Async Functions#}</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<pre>{#syntax#}await{#endsyntax#}</pre>
|
||||
</th>
|
||||
<td>
|
||||
{#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.
|
||||
{#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.
|
||||
<ul>
|
||||
<li>See also {#link|Async Functions#}</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<pre>{#syntax#}break{#endsyntax#}</pre>
|
||||
@ -7782,6 +7785,18 @@ fn readU32Be() u32 {}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<pre>{#syntax#}usingnamespace{#endsyntax#}</pre>
|
||||
</th>
|
||||
<td>
|
||||
{#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,
|
||||
which must be a struct, union, or enum, into the current scope.
|
||||
<ul>
|
||||
<li>See also {#link|usingnamespace#}</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<pre>{#syntax#}var{#endsyntax#}</pre>
|
||||
@ -7836,11 +7851,11 @@ fn readU32Be() u32 {}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Grammar#}
|
||||
{#syntax_block|peg|grammar.peg#}
|
||||
Root <- skip ContainerMembers eof
|
||||
{#syntax_block|peg|grammar.y#}
|
||||
Root <- skip container_doc_comment? ContainerMembers eof
|
||||
|
||||
# *** Top level ***
|
||||
ContainerMembers <- container_doc_comment? ContainerDeclaration* (ContainerField COMMA)* (ContainerField / ContainerDeclaration*)
|
||||
ContainerMembers <- ContainerDeclaration* (ContainerField COMMA)* (ContainerField / ContainerDeclaration*)
|
||||
|
||||
ContainerDeclaration <- TestDecl / ComptimeDecl / doc_comment? KEYWORD_pub? Decl
|
||||
|
||||
@ -7851,6 +7866,7 @@ ComptimeDecl <- KEYWORD_comptime Block
|
||||
Decl
|
||||
<- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)
|
||||
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? GlobalVarDecl
|
||||
/ KEYWORD_usingnamespace Expr SEMICOLON
|
||||
|
||||
FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
|
||||
|
||||
@ -7869,6 +7885,7 @@ Statement
|
||||
/ KEYWORD_errdefer Payload? BlockExprStatement
|
||||
/ IfStatement
|
||||
/ LabeledStatement
|
||||
/ SwitchExpr
|
||||
/ VarDeclExprStatement
|
||||
|
||||
ComptimeStatement
|
||||
@ -7879,7 +7896,7 @@ IfStatement
|
||||
<- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
||||
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
||||
|
||||
LabeledStatement <- BlockLabel? (Block / LoopStatement / SwitchExpr)
|
||||
LabeledStatement <- BlockLabel? (Block / LoopStatement)
|
||||
|
||||
LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
|
||||
|
||||
@ -7933,7 +7950,7 @@ PrimaryExpr
|
||||
/ KEYWORD_break BreakLabel? Expr?
|
||||
/ KEYWORD_comptime Expr
|
||||
/ KEYWORD_nosuspend Expr
|
||||
/ KEYWORD_continue BreakLabel? Expr?
|
||||
/ KEYWORD_continue BreakLabel?
|
||||
/ KEYWORD_resume Expr
|
||||
/ KEYWORD_return Expr?
|
||||
/ BlockLabel? LoopExpr
|
||||
@ -7962,7 +7979,8 @@ TypeExpr <- PrefixTypeOp* ErrorUnionExpr
|
||||
ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
|
||||
|
||||
SuffixExpr
|
||||
<- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||
<- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
|
||||
/ PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||
|
||||
PrimaryTypeExpr
|
||||
<- BUILTINIDENTIFIER FnCallArguments
|
||||
@ -7983,6 +8001,7 @@ PrimaryTypeExpr
|
||||
/ KEYWORD_anyframe
|
||||
/ KEYWORD_unreachable
|
||||
/ STRINGLITERAL
|
||||
/ SwitchExpr
|
||||
|
||||
ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
|
||||
|
||||
@ -7995,7 +8014,6 @@ IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
|
||||
LabeledTypeExpr
|
||||
<- BlockLabel Block
|
||||
/ BlockLabel? LoopTypeExpr
|
||||
/ BlockLabel? SwitchExpr
|
||||
|
||||
LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
|
||||
|
||||
@ -8016,7 +8034,7 @@ AsmInput <- COLON AsmInputList AsmClobbers?
|
||||
|
||||
AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
|
||||
|
||||
AsmClobbers <- COLON Expr
|
||||
AsmClobbers <- COLON StringList
|
||||
|
||||
# *** Helper grammar ***
|
||||
BreakLabel <- COLON IDENTIFIER
|
||||
@ -8138,6 +8156,7 @@ PrefixOp
|
||||
/ MINUSPERCENT
|
||||
/ AMPERSAND
|
||||
/ KEYWORD_try
|
||||
/ KEYWORD_await
|
||||
|
||||
PrefixTypeOp
|
||||
<- QUESTIONMARK
|
||||
@ -8165,7 +8184,7 @@ PtrTypeStart
|
||||
ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
|
||||
|
||||
# ContainerDecl specific
|
||||
ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
|
||||
ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE
|
||||
|
||||
ContainerDeclType
|
||||
<- KEYWORD_struct (LPAREN Expr RPAREN)?
|
||||
@ -8185,6 +8204,8 @@ AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
|
||||
|
||||
AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
|
||||
|
||||
StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
|
||||
|
||||
ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
|
||||
|
||||
ExprList <- (Expr COMMA)* Expr?
|
||||
@ -8231,7 +8252,7 @@ oxC2_oxDF <- [\302-\337]
|
||||
# [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF]
|
||||
# 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF]
|
||||
|
||||
multibyte_utf8 <-
|
||||
mb_utf8_literal <-
|
||||
oxF4 ox80_ox8F ox80_oxBF ox80_oxBF
|
||||
/ oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF
|
||||
/ oxF0 ox90_0xBF ox80_oxBF ox80_oxBF
|
||||
@ -8241,47 +8262,46 @@ multibyte_utf8 <-
|
||||
/ oxE0 oxA0_oxBF ox80_oxBF
|
||||
/ oxC2_oxDF ox80_oxBF
|
||||
|
||||
non_control_ascii <- [\040-\176]
|
||||
ascii_char_not_nl_slash_squote <- [\000-\011\013-\046\050-\133\135-\177]
|
||||
|
||||
char_escape
|
||||
<- "\\x" hex hex
|
||||
/ "\\u{" hex+ "}"
|
||||
/ "\\" [nr\\t'"]
|
||||
char_char
|
||||
<- multibyte_utf8
|
||||
<- mb_utf8_literal
|
||||
/ char_escape
|
||||
/ ![\\'\n] non_control_ascii
|
||||
/ ascii_char_not_nl_slash_squote
|
||||
|
||||
string_char
|
||||
<- multibyte_utf8
|
||||
/ char_escape
|
||||
/ ![\\"\n] non_control_ascii
|
||||
<- char_escape
|
||||
/ [^\\"\n]
|
||||
|
||||
container_doc_comment <- ('//!' [^\n]* [ \n]* skip)+
|
||||
doc_comment <- ('///' [^\n]* [ \n]* skip)+
|
||||
line_comment <- '//' ![!/][^\n]* / '////' [^\n]*
|
||||
line_string <- ('\\\\' [^\n]* [ \n]*)+
|
||||
line_string <- ("\\\\" [^\n]* [ \n]*)+
|
||||
skip <- ([ \n] / line_comment)*
|
||||
|
||||
CHAR_LITERAL <- ['] char_char ['] skip
|
||||
CHAR_LITERAL <- "'" char_char "'" skip
|
||||
FLOAT
|
||||
<- '0x' hex_int '.' hex_int ([pP] [-+]? dec_int)? skip
|
||||
/ dec_int '.' dec_int ([eE] [-+]? dec_int)? skip
|
||||
/ '0x' hex_int [pP] [-+]? dec_int skip
|
||||
<- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
|
||||
/ dec_int "." dec_int ([eE] [-+]? dec_int)? skip
|
||||
/ "0x" hex_int [pP] [-+]? dec_int skip
|
||||
/ dec_int [eE] [-+]? dec_int skip
|
||||
INTEGER
|
||||
<- '0b' bin_int skip
|
||||
/ '0o' oct_int skip
|
||||
/ '0x' hex_int skip
|
||||
<- "0b" bin_int skip
|
||||
/ "0o" oct_int skip
|
||||
/ "0x" hex_int skip
|
||||
/ dec_int skip
|
||||
STRINGLITERALSINGLE <- ["] string_char* ["] skip
|
||||
STRINGLITERALSINGLE <- "\"" string_char* "\"" skip
|
||||
STRINGLITERAL
|
||||
<- STRINGLITERALSINGLE
|
||||
/ (line_string skip)+
|
||||
IDENTIFIER
|
||||
<- !keyword [A-Za-z_] [A-Za-z0-9_]* skip
|
||||
/ '@' STRINGLITERALSINGLE
|
||||
BUILTINIDENTIFIER <- '@'[A-Za-z_][A-Za-z0-9_]* skip
|
||||
/ "@" STRINGLITERALSINGLE
|
||||
BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
|
||||
|
||||
|
||||
AMPERSAND <- '&' ![=] skip
|
||||
@ -8357,6 +8377,8 @@ KEYWORD_and <- 'and' end_of_word
|
||||
KEYWORD_anyframe <- 'anyframe' end_of_word
|
||||
KEYWORD_anytype <- 'anytype' end_of_word
|
||||
KEYWORD_asm <- 'asm' end_of_word
|
||||
KEYWORD_async <- 'async' end_of_word
|
||||
KEYWORD_await <- 'await' end_of_word
|
||||
KEYWORD_break <- 'break' end_of_word
|
||||
KEYWORD_callconv <- 'callconv' end_of_word
|
||||
KEYWORD_catch <- 'catch' end_of_word
|
||||
@ -8393,13 +8415,14 @@ KEYWORD_threadlocal <- 'threadlocal' end_of_word
|
||||
KEYWORD_try <- 'try' end_of_word
|
||||
KEYWORD_union <- 'union' end_of_word
|
||||
KEYWORD_unreachable <- 'unreachable' end_of_word
|
||||
KEYWORD_usingnamespace <- 'usingnamespace' end_of_word
|
||||
KEYWORD_var <- 'var' end_of_word
|
||||
KEYWORD_volatile <- 'volatile' end_of_word
|
||||
KEYWORD_while <- 'while' end_of_word
|
||||
|
||||
keyword <- KEYWORD_addrspace / KEYWORD_align / KEYWORD_allowzero / KEYWORD_and
|
||||
/ KEYWORD_anyframe / KEYWORD_anytype / KEYWORD_asm
|
||||
/ KEYWORD_break / KEYWORD_callconv / KEYWORD_catch
|
||||
/ KEYWORD_anyframe / KEYWORD_anytype / KEYWORD_asm / KEYWORD_async
|
||||
/ KEYWORD_await / KEYWORD_break / KEYWORD_callconv / KEYWORD_catch
|
||||
/ KEYWORD_comptime / KEYWORD_const / KEYWORD_continue / KEYWORD_defer
|
||||
/ KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer / KEYWORD_error / KEYWORD_export
|
||||
/ KEYWORD_extern / KEYWORD_fn / KEYWORD_for / KEYWORD_if
|
||||
@ -8408,7 +8431,7 @@ keyword <- KEYWORD_addrspace / KEYWORD_align / KEYWORD_allowzero / KEYWORD_and
|
||||
/ KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
|
||||
/ KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test
|
||||
/ KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable
|
||||
/ KEYWORD_var / KEYWORD_volatile / KEYWORD_while
|
||||
/ KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
|
||||
{#end_syntax_block#}
|
||||
{#header_close#}
|
||||
{#header_open|Zen#}
|
||||
|
||||
@ -53,7 +53,8 @@ pub fn syscall1(number: usize, arg1: usize) usize {
|
||||
// memory locations - not only the memory pointed to by a declared indirect
|
||||
// output. In this example we list $rcx and $r11 because it is known the
|
||||
// kernel syscall does not preserve these registers.
|
||||
: .{ .rcx = true, .r11 = true });
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
// syntax
|
||||
|
||||
@ -17,7 +17,7 @@ pub fn main() !void {
|
||||
.maximum = 0.20,
|
||||
};
|
||||
const category = threshold.categorize(0.90);
|
||||
try std.fs.File.stdout().writeAll(@tagName(category));
|
||||
try std.io.getStdOut().writeAll(@tagName(category));
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
@ -4,10 +4,8 @@ pub fn build(b: *std.Build) void {
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "example",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("example.zig"),
|
||||
.optimize = optimize,
|
||||
}),
|
||||
.root_source_file = b.path("example.zig"),
|
||||
.optimize = optimize,
|
||||
});
|
||||
b.default_step.dependOn(&exe.step);
|
||||
}
|
||||
|
||||
@ -1,22 +1,17 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const lib = b.addLibrary(.{
|
||||
.linkage = .dynamic,
|
||||
const lib = b.addSharedLibrary(.{
|
||||
.name = "mathtest",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("mathtest.zig"),
|
||||
}),
|
||||
.root_source_file = b.path("mathtest.zig"),
|
||||
.version = .{ .major = 1, .minor = 0, .patch = 0 },
|
||||
});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.root_module = b.createModule(.{
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
|
||||
exe.root_module.linkLibrary(lib);
|
||||
exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
|
||||
exe.linkLibrary(lib);
|
||||
exe.linkSystemLibrary("c");
|
||||
|
||||
b.default_step.dependOn(&exe.step);
|
||||
|
||||
|
||||
@ -3,19 +3,15 @@ const std = @import("std");
|
||||
pub fn build(b: *std.Build) void {
|
||||
const obj = b.addObject(.{
|
||||
.name = "base64",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("base64.zig"),
|
||||
}),
|
||||
.root_source_file = b.path("base64.zig"),
|
||||
});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.root_module = b.createModule(.{
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
|
||||
exe.root_module.addObject(obj);
|
||||
exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
|
||||
exe.addObject(obj);
|
||||
exe.linkSystemLibrary("c");
|
||||
b.installArtifact(exe);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const print = std.debug.print;
|
||||
|
||||
pub fn main() void {
|
||||
test "defer unwinding" {
|
||||
print("\n", .{});
|
||||
|
||||
defer {
|
||||
@ -18,4 +19,4 @@ pub fn main() void {
|
||||
}
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// test
|
||||
|
||||
@ -15,8 +15,8 @@ pub fn main() void {
|
||||
break :blk .{ min, max };
|
||||
};
|
||||
|
||||
print("min = {}\n", .{ min });
|
||||
print("max = {}\n", .{ max });
|
||||
print("min = {}", .{ min });
|
||||
print("max = {}", .{ max });
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
|
||||
@ -2,6 +2,6 @@ comptime {
|
||||
@export(&internalName, .{ .name = "foo", .linkage = .strong });
|
||||
}
|
||||
|
||||
fn internalName() callconv(.c) void {}
|
||||
fn internalName() callconv(.C) void {}
|
||||
|
||||
// obj
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
try std.fs.File.stdout().writeAll("Hello, World!\n");
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Hello, {s}!\n", .{"world"});
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
std.debug.print("Hello, {s}!\n", .{"World"});
|
||||
std.debug.print("Hello, world!\n", .{});
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
|
||||
@ -15,7 +15,8 @@ pub fn syscall1(number: usize, arg1: usize) usize {
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (number),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
: .{ .rcx = true, .r11 = true });
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
@ -25,7 +26,8 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3),
|
||||
: .{ .rcx = true, .r11 = true });
|
||||
: "rcx", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
test "inline function call" {
|
||||
if (foo(1200, 34) != 1234) {
|
||||
@compileError("bad");
|
||||
}
|
||||
}
|
||||
|
||||
inline fn foo(a: i32, b: i32) i32 {
|
||||
std.debug.print("runtime a = {} b = {}", .{ a, b });
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// test
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
pub const GpioRegister = packed struct(u8) {
|
||||
GPIO0: bool,
|
||||
GPIO1: bool,
|
||||
GPIO2: bool,
|
||||
GPIO3: bool,
|
||||
reserved: u4 = 0,
|
||||
};
|
||||
|
||||
const gpio: *volatile GpioRegister = @ptrFromInt(0x0123);
|
||||
|
||||
pub fn writeToGpio(new_states: GpioRegister) void {
|
||||
// Example of what not to do:
|
||||
// BAD! gpio.GPIO0 = true; BAD!
|
||||
|
||||
// Instead, do this:
|
||||
gpio.* = new_states;
|
||||
}
|
||||
|
||||
// syntax
|
||||
@ -1,4 +1,3 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
@ -6,8 +5,6 @@ pub fn main() void {
|
||||
_ = &x;
|
||||
const y = @shrExact(x, 2);
|
||||
std.debug.print("value: {}\n", .{y});
|
||||
|
||||
if ((builtin.cpu.arch.isRISCV() or builtin.cpu.arch.isLoongArch() or builtin.cpu.arch == .s390x) and builtin.zig_backend == .stage2_llvm) @panic("https://github.com/ziglang/zig/issues/24304");
|
||||
}
|
||||
|
||||
// exe=fail
|
||||
|
||||
@ -11,7 +11,7 @@ pub const std_options: std.Options = .{
|
||||
|
||||
fn myLogFn(
|
||||
comptime level: std.log.Level,
|
||||
comptime scope: @EnumLiteral(),
|
||||
comptime scope: @Type(.enum_literal),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
|
||||
@ -67,11 +67,4 @@ test "*T to *[1]T" {
|
||||
try expect(z[0] == 1234);
|
||||
}
|
||||
|
||||
// Sentinel-terminated slices can be coerced into sentinel-terminated pointers
|
||||
test "[:x]T to [*:x]T" {
|
||||
const buf: [:0]const u8 = "hello";
|
||||
const buf2: [*:0]const u8 = buf;
|
||||
try expect(buf2[4] == 'o');
|
||||
}
|
||||
|
||||
// test
|
||||
|
||||
@ -41,7 +41,7 @@ test "coercion between unions and enums" {
|
||||
try expect(u_4.tag() == 1);
|
||||
|
||||
// The following example is invalid.
|
||||
// error: coercion from enum '@EnumLiteral()' to union 'test_coerce_unions_enum.U2' must initialize 'f32' field 'b'
|
||||
// error: coercion from enum '@TypeOf(.enum_literal)' to union 'test_coerce_unions_enum.U2' must initialize 'f32' field 'b'
|
||||
//var u_5: U2 = .b;
|
||||
//try expect(u_5.tag() == 2);
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
comptime {
|
||||
const x = @shlExact(@as(u8, 0b01010101), 2);
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// test_error=overflow of integer type 'u8' with value '340'
|
||||
6
doc/langref/test_comptime_shlExact_overwlow.zig
Normal file
6
doc/langref/test_comptime_shlExact_overwlow.zig
Normal file
@ -0,0 +1,6 @@
|
||||
comptime {
|
||||
const x = @shlExact(@as(u8, 0b01010101), 2);
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// test_error=operation caused overflow
|
||||
@ -2,7 +2,7 @@ const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
fn add(count: c_int, ...) callconv(.c) c_int {
|
||||
fn add(count: c_int, ...) callconv(.C) c_int {
|
||||
var ap = @cVaStart();
|
||||
defer @cVaEnd(&ap);
|
||||
var i: usize = 0;
|
||||
@ -22,10 +22,6 @@ test "defining a variadic function" {
|
||||
// https://github.com/ziglang/zig/issues/16961
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.cpu.arch == .s390x) {
|
||||
// https://github.com/ziglang/zig/issues/21350#issuecomment-3543006475
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
|
||||
try std.testing.expectEqual(@as(c_int, 0), add(0));
|
||||
try std.testing.expectEqual(@as(c_int, 1), add(1, @as(c_int, 1)));
|
||||
|
||||
@ -23,7 +23,8 @@ export fn sub(a: i8, b: i8) i8 {
|
||||
// dynamically. The quoted identifier after the extern keyword specifies
|
||||
// the library that has the function. (e.g. "c" -> libc.so)
|
||||
// The callconv specifier changes the calling convention of the function.
|
||||
extern "kernel32" fn ExitProcess(exit_code: u32) callconv(.winapi) noreturn;
|
||||
const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .Stdcall else .C;
|
||||
extern "kernel32" fn ExitProcess(exit_code: u32) callconv(WINAPI) noreturn;
|
||||
extern "c" fn atan2(a: f64, b: f64) f64;
|
||||
|
||||
// The @branchHint builtin can be used to tell the optimizer that a function is rarely called ("cold").
|
||||
@ -34,7 +35,7 @@ fn abort() noreturn {
|
||||
|
||||
// The naked calling convention makes a function not have any function prologue or epilogue.
|
||||
// This can be useful when integrating with assembly.
|
||||
fn _start() callconv(.naked) noreturn {
|
||||
fn _start() callconv(.Naked) noreturn {
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
@ -19,4 +19,3 @@ test "global assembly" {
|
||||
|
||||
// test
|
||||
// target=x86_64-linux
|
||||
// llvm=true
|
||||
|
||||
@ -5,4 +5,4 @@ test "integer cast panic" {
|
||||
_ = b;
|
||||
}
|
||||
|
||||
// test_error=integer does not fit in destination type
|
||||
// test_error=cast truncated bits
|
||||
|
||||
@ -3,7 +3,7 @@ const builtin = @import("builtin");
|
||||
const native_arch = builtin.cpu.arch;
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .{ .x86_stdcall = .{} } else .c;
|
||||
const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .Stdcall else .C;
|
||||
extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(WINAPI) noreturn;
|
||||
|
||||
test "foo" {
|
||||
|
||||
@ -2,7 +2,7 @@ const Derp = opaque {};
|
||||
const Wat = opaque {};
|
||||
|
||||
extern fn bar(d: *Derp) void;
|
||||
fn foo(w: *Wat) callconv(.c) void {
|
||||
fn foo(w: *Wat) callconv(.C) void {
|
||||
bar(w);
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ const S = packed struct {
|
||||
test "overaligned pointer to packed struct" {
|
||||
var foo: S align(4) = .{ .a = 1, .b = 2 };
|
||||
const ptr: *align(4) S = &foo;
|
||||
const ptr_to_b = &ptr.b;
|
||||
const ptr_to_b: *u32 = &ptr.b;
|
||||
try expect(ptr_to_b.* == 2);
|
||||
}
|
||||
|
||||
|
||||
@ -7,10 +7,4 @@ test "vector @splat" {
|
||||
try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 }));
|
||||
}
|
||||
|
||||
test "array @splat" {
|
||||
const scalar: u32 = 5;
|
||||
const result: [4]u32 = @splat(scalar);
|
||||
try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 }));
|
||||
}
|
||||
|
||||
// test
|
||||
|
||||
@ -8,22 +8,20 @@ const Instruction = enum {
|
||||
};
|
||||
|
||||
fn evaluate(initial_stack: []const i32, code: []const Instruction) !i32 {
|
||||
var buffer: [8]i32 = undefined;
|
||||
var stack = std.ArrayList(i32).initBuffer(&buffer);
|
||||
try stack.appendSliceBounded(initial_stack);
|
||||
var stack = try std.BoundedArray(i32, 8).fromSlice(initial_stack);
|
||||
var ip: usize = 0;
|
||||
|
||||
return vm: switch (code[ip]) {
|
||||
// Because all code after `continue` is unreachable, this branch does
|
||||
// not provide a result.
|
||||
.add => {
|
||||
try stack.appendBounded(stack.pop().? + stack.pop().?);
|
||||
try stack.append(stack.pop().? + stack.pop().?);
|
||||
|
||||
ip += 1;
|
||||
continue :vm code[ip];
|
||||
},
|
||||
.mul => {
|
||||
try stack.appendBounded(stack.pop().? * stack.pop().?);
|
||||
try stack.append(stack.pop().? * stack.pop().?);
|
||||
|
||||
ip += 1;
|
||||
continue :vm code[ip];
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const Tagged = union(enum(u32)) {
|
||||
int: i64 = 123,
|
||||
boolean: bool = 67,
|
||||
};
|
||||
|
||||
test "tag values" {
|
||||
const int: Tagged = .{ .int = -40 };
|
||||
try expect(@intFromEnum(int) == 123);
|
||||
|
||||
const boolean: Tagged = .{ .boolean = false };
|
||||
try expect(@intFromEnum(boolean) == 67);
|
||||
}
|
||||
|
||||
// test
|
||||
8
doc/langref/test_usingnamespace.zig
Normal file
8
doc/langref/test_usingnamespace.zig
Normal file
@ -0,0 +1,8 @@
|
||||
test "using std namespace" {
|
||||
const S = struct {
|
||||
usingnamespace @import("std");
|
||||
};
|
||||
try S.testing.expect(true);
|
||||
}
|
||||
|
||||
// test
|
||||
@ -17,7 +17,7 @@ test "Basic vector usage" {
|
||||
}
|
||||
|
||||
test "Conversion between vectors, arrays, and slices" {
|
||||
// Vectors can be coerced to arrays, and vice versa.
|
||||
// Vectors and fixed-length arrays can be automatically assigned back and forth
|
||||
const arr1: [4]f32 = [_]f32{ 1.1, 3.2, 4.5, 5.6 };
|
||||
const vec: @Vector(4, f32) = arr1;
|
||||
const arr2: [4]f32 = vec;
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
const std = @import("std");
|
||||
|
||||
test "detect leak" {
|
||||
const gpa = std.testing.allocator;
|
||||
var list: std.ArrayList(u21) = .empty;
|
||||
// missing `defer list.deinit(gpa);`
|
||||
try list.append(gpa, '☔');
|
||||
var list = std.ArrayList(u21).init(std.testing.allocator);
|
||||
// missing `defer list.deinit();`
|
||||
try list.append('☔');
|
||||
|
||||
try std.testing.expect(list.items.len == 1);
|
||||
}
|
||||
|
||||
@ -4,11 +4,6 @@ const std = @import("std");
|
||||
const os = std.os;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
// Custom error set definition:
|
||||
const ExampleErrorSet = error{
|
||||
ExampleErrorVariant,
|
||||
};
|
||||
|
||||
pub fn main() void {
|
||||
// integers
|
||||
const one_plus_one: i32 = 1 + 1;
|
||||
@ -41,7 +36,7 @@ pub fn main() void {
|
||||
});
|
||||
|
||||
// error union
|
||||
var number_or_error: ExampleErrorSet!i32 = ExampleErrorSet.ExampleErrorVariant;
|
||||
var number_or_error: anyerror!i32 = error.ArgNotFound;
|
||||
|
||||
print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{
|
||||
@TypeOf(number_or_error),
|
||||
|
||||
@ -1,378 +0,0 @@
|
||||
// Server timestamp.
|
||||
var start_fuzzing_timestamp: i64 = undefined;
|
||||
|
||||
const js = struct {
|
||||
extern "fuzz" fn requestSources() void;
|
||||
extern "fuzz" fn ready() void;
|
||||
|
||||
extern "fuzz" fn updateStats(html_ptr: [*]const u8, html_len: usize) void;
|
||||
extern "fuzz" fn updateEntryPoints(html_ptr: [*]const u8, html_len: usize) void;
|
||||
extern "fuzz" fn updateSource(html_ptr: [*]const u8, html_len: usize) void;
|
||||
extern "fuzz" fn updateCoverage(covered_ptr: [*]const SourceLocationIndex, covered_len: u32) void;
|
||||
};
|
||||
|
||||
pub fn sourceIndexMessage(msg_bytes: []u8) error{OutOfMemory}!void {
|
||||
Walk.files.clearRetainingCapacity();
|
||||
Walk.decls.clearRetainingCapacity();
|
||||
Walk.modules.clearRetainingCapacity();
|
||||
recent_coverage_update.clearRetainingCapacity();
|
||||
selected_source_location = null;
|
||||
|
||||
js.requestSources();
|
||||
|
||||
const Header = abi.fuzz.SourceIndexHeader;
|
||||
const header: Header = @bitCast(msg_bytes[0..@sizeOf(Header)].*);
|
||||
|
||||
const directories_start = @sizeOf(Header);
|
||||
const directories_end = directories_start + header.directories_len * @sizeOf(Coverage.String);
|
||||
const files_start = directories_end;
|
||||
const files_end = files_start + header.files_len * @sizeOf(Coverage.File);
|
||||
const source_locations_start = files_end;
|
||||
const source_locations_end = source_locations_start + header.source_locations_len * @sizeOf(Coverage.SourceLocation);
|
||||
const string_bytes = msg_bytes[source_locations_end..][0..header.string_bytes_len];
|
||||
|
||||
const directories: []const Coverage.String = @alignCast(std.mem.bytesAsSlice(Coverage.String, msg_bytes[directories_start..directories_end]));
|
||||
const files: []const Coverage.File = @alignCast(std.mem.bytesAsSlice(Coverage.File, msg_bytes[files_start..files_end]));
|
||||
const source_locations: []const Coverage.SourceLocation = @alignCast(std.mem.bytesAsSlice(Coverage.SourceLocation, msg_bytes[source_locations_start..source_locations_end]));
|
||||
|
||||
start_fuzzing_timestamp = header.start_timestamp;
|
||||
try updateCoverageSources(directories, files, source_locations, string_bytes);
|
||||
js.ready();
|
||||
}
|
||||
|
||||
var coverage = Coverage.init;
|
||||
/// Index of type `SourceLocationIndex`.
|
||||
var coverage_source_locations: std.ArrayList(Coverage.SourceLocation) = .empty;
|
||||
/// Contains the most recent coverage update message, unmodified.
|
||||
var recent_coverage_update: std.ArrayListAlignedUnmanaged(u8, .of(u64)) = .empty;
|
||||
|
||||
fn updateCoverageSources(
|
||||
directories: []const Coverage.String,
|
||||
files: []const Coverage.File,
|
||||
source_locations: []const Coverage.SourceLocation,
|
||||
string_bytes: []const u8,
|
||||
) !void {
|
||||
coverage.directories.clearRetainingCapacity();
|
||||
coverage.files.clearRetainingCapacity();
|
||||
coverage.string_bytes.clearRetainingCapacity();
|
||||
coverage_source_locations.clearRetainingCapacity();
|
||||
|
||||
try coverage_source_locations.appendSlice(gpa, source_locations);
|
||||
try coverage.string_bytes.appendSlice(gpa, string_bytes);
|
||||
|
||||
try coverage.files.entries.resize(gpa, files.len);
|
||||
@memcpy(coverage.files.entries.items(.key), files);
|
||||
try coverage.files.reIndexContext(gpa, .{ .string_bytes = coverage.string_bytes.items });
|
||||
|
||||
try coverage.directories.entries.resize(gpa, directories.len);
|
||||
@memcpy(coverage.directories.entries.items(.key), directories);
|
||||
try coverage.directories.reIndexContext(gpa, .{ .string_bytes = coverage.string_bytes.items });
|
||||
}
|
||||
|
||||
pub fn coverageUpdateMessage(msg_bytes: []u8) error{OutOfMemory}!void {
|
||||
recent_coverage_update.clearRetainingCapacity();
|
||||
recent_coverage_update.appendSlice(gpa, msg_bytes) catch @panic("OOM");
|
||||
try updateStats();
|
||||
try updateCoverage();
|
||||
}
|
||||
|
||||
var entry_points: std.ArrayList(SourceLocationIndex) = .empty;
|
||||
|
||||
pub fn entryPointsMessage(msg_bytes: []u8) error{OutOfMemory}!void {
|
||||
const header: abi.fuzz.EntryPointHeader = @bitCast(msg_bytes[0..@sizeOf(abi.fuzz.EntryPointHeader)].*);
|
||||
const slis: []align(1) const SourceLocationIndex = @ptrCast(msg_bytes[@sizeOf(abi.fuzz.EntryPointHeader)..]);
|
||||
assert(slis.len == header.locsLen());
|
||||
try entry_points.resize(gpa, slis.len);
|
||||
@memcpy(entry_points.items, slis);
|
||||
try updateEntryPoints();
|
||||
}
|
||||
|
||||
/// Index into `coverage_source_locations`.
|
||||
const SourceLocationIndex = enum(u32) {
|
||||
_,
|
||||
|
||||
fn haveCoverage(sli: SourceLocationIndex) bool {
|
||||
return @intFromEnum(sli) < coverage_source_locations.items.len;
|
||||
}
|
||||
|
||||
fn ptr(sli: SourceLocationIndex) *Coverage.SourceLocation {
|
||||
return &coverage_source_locations.items[@intFromEnum(sli)];
|
||||
}
|
||||
|
||||
fn sourceLocationLinkHtml(
|
||||
sli: SourceLocationIndex,
|
||||
out: *std.ArrayList(u8),
|
||||
focused: bool,
|
||||
) error{OutOfMemory}!void {
|
||||
const sl = sli.ptr();
|
||||
try out.print(gpa, "<code{s}>", .{
|
||||
@as([]const u8, if (focused) " class=\"status-running\"" else ""),
|
||||
});
|
||||
try sli.appendPath(out);
|
||||
try out.print(gpa, ":{d}:{d} </code><button class=\"linkish\" onclick=\"wasm_exports.fuzzSelectSli({d});\">View</button>", .{
|
||||
sl.line,
|
||||
sl.column,
|
||||
@intFromEnum(sli),
|
||||
});
|
||||
}
|
||||
|
||||
fn appendPath(sli: SourceLocationIndex, out: *std.ArrayList(u8)) error{OutOfMemory}!void {
|
||||
const sl = sli.ptr();
|
||||
const file = coverage.fileAt(sl.file);
|
||||
const file_name = coverage.stringAt(file.basename);
|
||||
const dir_name = coverage.stringAt(coverage.directories.keys()[file.directory_index]);
|
||||
try html_render.appendEscaped(out, dir_name);
|
||||
try out.appendSlice(gpa, "/");
|
||||
try html_render.appendEscaped(out, file_name);
|
||||
}
|
||||
|
||||
fn toWalkFile(sli: SourceLocationIndex) ?Walk.File.Index {
|
||||
var buf: std.ArrayList(u8) = .empty;
|
||||
defer buf.deinit(gpa);
|
||||
sli.appendPath(&buf) catch @panic("OOM");
|
||||
return @enumFromInt(Walk.files.getIndex(buf.items) orelse return null);
|
||||
}
|
||||
|
||||
fn fileHtml(
|
||||
sli: SourceLocationIndex,
|
||||
out: *std.ArrayList(u8),
|
||||
) error{ OutOfMemory, SourceUnavailable }!void {
|
||||
const walk_file_index = sli.toWalkFile() orelse return error.SourceUnavailable;
|
||||
const root_node = walk_file_index.findRootDecl().get().ast_node;
|
||||
var annotations: std.ArrayList(html_render.Annotation) = .empty;
|
||||
defer annotations.deinit(gpa);
|
||||
try computeSourceAnnotations(sli.ptr().file, walk_file_index, &annotations, coverage_source_locations.items);
|
||||
html_render.fileSourceHtml(walk_file_index, out, root_node, .{
|
||||
.source_location_annotations = annotations.items,
|
||||
}) catch |err| {
|
||||
fatal("unable to render source: {s}", .{@errorName(err)});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn computeSourceAnnotations(
|
||||
cov_file_index: Coverage.File.Index,
|
||||
walk_file_index: Walk.File.Index,
|
||||
annotations: *std.ArrayList(html_render.Annotation),
|
||||
source_locations: []const Coverage.SourceLocation,
|
||||
) !void {
|
||||
// Collect all the source locations from only this file into this array
|
||||
// first, then sort by line, col, so that we can collect annotations with
|
||||
// O(N) time complexity.
|
||||
var locs: std.ArrayList(SourceLocationIndex) = .empty;
|
||||
defer locs.deinit(gpa);
|
||||
|
||||
for (source_locations, 0..) |sl, sli_usize| {
|
||||
if (sl.file != cov_file_index) continue;
|
||||
const sli: SourceLocationIndex = @enumFromInt(sli_usize);
|
||||
try locs.append(gpa, sli);
|
||||
}
|
||||
|
||||
std.mem.sortUnstable(SourceLocationIndex, locs.items, {}, struct {
|
||||
pub fn lessThan(context: void, lhs: SourceLocationIndex, rhs: SourceLocationIndex) bool {
|
||||
_ = context;
|
||||
const lhs_ptr = lhs.ptr();
|
||||
const rhs_ptr = rhs.ptr();
|
||||
if (lhs_ptr.line < rhs_ptr.line) return true;
|
||||
if (lhs_ptr.line > rhs_ptr.line) return false;
|
||||
return lhs_ptr.column < rhs_ptr.column;
|
||||
}
|
||||
}.lessThan);
|
||||
|
||||
const source = walk_file_index.get_ast().source;
|
||||
var line: usize = 1;
|
||||
var column: usize = 1;
|
||||
var next_loc_index: usize = 0;
|
||||
for (source, 0..) |byte, offset| {
|
||||
if (byte == '\n') {
|
||||
line += 1;
|
||||
column = 1;
|
||||
} else {
|
||||
column += 1;
|
||||
}
|
||||
while (true) {
|
||||
if (next_loc_index >= locs.items.len) return;
|
||||
const next_sli = locs.items[next_loc_index];
|
||||
const next_sl = next_sli.ptr();
|
||||
if (next_sl.line > line or (next_sl.line == line and next_sl.column >= column)) break;
|
||||
try annotations.append(gpa, .{
|
||||
.file_byte_offset = offset,
|
||||
.dom_id = @intFromEnum(next_sli),
|
||||
});
|
||||
next_loc_index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export fn fuzzUnpackSources(tar_ptr: [*]u8, tar_len: usize) void {
|
||||
const tar_bytes = tar_ptr[0..tar_len];
|
||||
log.debug("received {d} bytes of sources.tar", .{tar_bytes.len});
|
||||
|
||||
unpackSourcesInner(tar_bytes) catch |err| {
|
||||
fatal("unable to unpack sources.tar: {s}", .{@errorName(err)});
|
||||
};
|
||||
}
|
||||
|
||||
fn unpackSourcesInner(tar_bytes: []u8) !void {
|
||||
var tar_reader: std.Io.Reader = .fixed(tar_bytes);
|
||||
var file_name_buffer: [1024]u8 = undefined;
|
||||
var link_name_buffer: [1024]u8 = undefined;
|
||||
var it: std.tar.Iterator = .init(&tar_reader, .{
|
||||
.file_name_buffer = &file_name_buffer,
|
||||
.link_name_buffer = &link_name_buffer,
|
||||
});
|
||||
while (try it.next()) |tar_file| {
|
||||
switch (tar_file.kind) {
|
||||
.file => {
|
||||
if (tar_file.size == 0 and tar_file.name.len == 0) break;
|
||||
if (std.mem.endsWith(u8, tar_file.name, ".zig")) {
|
||||
log.debug("found file: '{s}'", .{tar_file.name});
|
||||
const file_name = try gpa.dupe(u8, tar_file.name);
|
||||
// This is a hack to guess modules from the tar file contents. To handle modules
|
||||
// properly, the build system will need to change the structure here to have one
|
||||
// directory per module. This in turn requires compiler enhancements to allow
|
||||
// the build system to actually discover the required information.
|
||||
const mod_name, const is_module_root = p: {
|
||||
if (std.mem.find(u8, file_name, "std/")) |i| break :p .{ "std", std.mem.eql(u8, file_name[i + 4 ..], "std.zig") };
|
||||
if (std.mem.endsWith(u8, file_name, "/builtin.zig")) break :p .{ "builtin", true };
|
||||
break :p .{ "root", std.mem.endsWith(u8, file_name, "/root.zig") };
|
||||
};
|
||||
const gop = try Walk.modules.getOrPut(gpa, mod_name);
|
||||
const file: Walk.File.Index = @enumFromInt(Walk.files.entries.len);
|
||||
if (!gop.found_existing or is_module_root) gop.value_ptr.* = file;
|
||||
const file_bytes = tar_reader.take(@intCast(tar_file.size)) catch unreachable;
|
||||
it.unread_file_bytes = 0; // we have read the whole thing
|
||||
assert(file == try Walk.add_file(file_name, file_bytes));
|
||||
} else {
|
||||
log.warn("skipping: '{s}' - the tar creation should have done that", .{tar_file.name});
|
||||
}
|
||||
},
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn updateStats() error{OutOfMemory}!void {
|
||||
@setFloatMode(.optimized);
|
||||
|
||||
if (recent_coverage_update.items.len == 0) return;
|
||||
|
||||
const hdr: *abi.fuzz.CoverageUpdateHeader = @ptrCast(@alignCast(
|
||||
recent_coverage_update.items[0..@sizeOf(abi.fuzz.CoverageUpdateHeader)],
|
||||
));
|
||||
|
||||
const covered_src_locs: usize = n: {
|
||||
var n: usize = 0;
|
||||
const covered_bits = recent_coverage_update.items[@sizeOf(abi.fuzz.CoverageUpdateHeader)..];
|
||||
for (covered_bits) |byte| n += @popCount(byte);
|
||||
break :n n;
|
||||
};
|
||||
const total_src_locs = coverage_source_locations.items.len;
|
||||
|
||||
const avg_speed: f64 = speed: {
|
||||
const ns_elapsed: f64 = @floatFromInt(nsSince(start_fuzzing_timestamp));
|
||||
const n_runs: f64 = @floatFromInt(hdr.n_runs);
|
||||
break :speed n_runs / (ns_elapsed / std.time.ns_per_s);
|
||||
};
|
||||
|
||||
const html = try std.fmt.allocPrint(gpa,
|
||||
\\<span slot="stat-total-runs">{d}</span>
|
||||
\\<span slot="stat-unique-runs">{d} ({d:.1}%)</span>
|
||||
\\<span slot="stat-coverage">{d} / {d} ({d:.1}%)</span>
|
||||
\\<span slot="stat-speed">{d:.0}</span>
|
||||
, .{
|
||||
hdr.n_runs,
|
||||
hdr.unique_runs,
|
||||
@as(f64, @floatFromInt(hdr.unique_runs)) / @as(f64, @floatFromInt(hdr.n_runs)),
|
||||
covered_src_locs,
|
||||
total_src_locs,
|
||||
@as(f64, @floatFromInt(covered_src_locs)) / @as(f64, @floatFromInt(total_src_locs)),
|
||||
avg_speed,
|
||||
});
|
||||
defer gpa.free(html);
|
||||
|
||||
js.updateStats(html.ptr, html.len);
|
||||
}
|
||||
|
||||
fn updateEntryPoints() error{OutOfMemory}!void {
|
||||
var html: std.ArrayList(u8) = .empty;
|
||||
defer html.deinit(gpa);
|
||||
for (entry_points.items) |sli| {
|
||||
try html.appendSlice(gpa, "<li>");
|
||||
try sli.sourceLocationLinkHtml(&html, selected_source_location == sli);
|
||||
try html.appendSlice(gpa, "</li>\n");
|
||||
}
|
||||
js.updateEntryPoints(html.items.ptr, html.items.len);
|
||||
}
|
||||
|
||||
fn updateCoverage() error{OutOfMemory}!void {
|
||||
if (recent_coverage_update.items.len == 0) return;
|
||||
const want_file = (selected_source_location orelse return).ptr().file;
|
||||
|
||||
var covered: std.ArrayList(SourceLocationIndex) = .empty;
|
||||
defer covered.deinit(gpa);
|
||||
|
||||
// This code assumes 64-bit elements, which is incorrect if the executable
|
||||
// being fuzzed is not a 64-bit CPU. It also assumes little-endian which
|
||||
// can also be incorrect.
|
||||
comptime assert(abi.fuzz.CoverageUpdateHeader.trailing[0] == .pc_bits_usize);
|
||||
const n_bitset_elems = (coverage_source_locations.items.len + @bitSizeOf(u64) - 1) / @bitSizeOf(u64);
|
||||
const covered_bits = std.mem.bytesAsSlice(
|
||||
u64,
|
||||
recent_coverage_update.items[@sizeOf(abi.fuzz.CoverageUpdateHeader)..][0 .. n_bitset_elems * @sizeOf(u64)],
|
||||
);
|
||||
var sli: SourceLocationIndex = @enumFromInt(0);
|
||||
for (covered_bits) |elem| {
|
||||
try covered.ensureUnusedCapacity(gpa, 64);
|
||||
for (0..@bitSizeOf(u64)) |i| {
|
||||
if ((elem & (@as(u64, 1) << @intCast(i))) != 0) {
|
||||
if (sli.ptr().file == want_file) {
|
||||
covered.appendAssumeCapacity(sli);
|
||||
}
|
||||
}
|
||||
sli = @enumFromInt(@intFromEnum(sli) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
js.updateCoverage(covered.items.ptr, covered.items.len);
|
||||
}
|
||||
|
||||
fn updateSource() error{OutOfMemory}!void {
|
||||
if (recent_coverage_update.items.len == 0) return;
|
||||
const file_sli = selected_source_location.?;
|
||||
var html: std.ArrayList(u8) = .empty;
|
||||
defer html.deinit(gpa);
|
||||
file_sli.fileHtml(&html) catch |err| switch (err) {
|
||||
error.OutOfMemory => |e| return e,
|
||||
error.SourceUnavailable => {},
|
||||
};
|
||||
js.updateSource(html.items.ptr, html.items.len);
|
||||
}
|
||||
|
||||
var selected_source_location: ?SourceLocationIndex = null;
|
||||
|
||||
/// This function is not used directly by `main.js`, but a reference to it is
|
||||
/// emitted by `SourceLocationIndex.sourceLocationLinkHtml`.
|
||||
export fn fuzzSelectSli(sli: SourceLocationIndex) void {
|
||||
if (!sli.haveCoverage()) return;
|
||||
selected_source_location = sli;
|
||||
updateEntryPoints() catch @panic("out of memory"); // highlights the selected one green
|
||||
updateSource() catch @panic("out of memory");
|
||||
updateCoverage() catch @panic("out of memory");
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Coverage = std.debug.Coverage;
|
||||
const abi = std.Build.abi;
|
||||
const assert = std.debug.assert;
|
||||
const gpa = std.heap.wasm_allocator;
|
||||
|
||||
const Walk = @import("Walk");
|
||||
const html_render = @import("html_render");
|
||||
|
||||
const nsSince = @import("main.zig").nsSince;
|
||||
const Slice = @import("main.zig").Slice;
|
||||
const fatal = @import("main.zig").fatal;
|
||||
const log = std.log;
|
||||
const String = Slice(u8);
|
||||
@ -1,217 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<title>Zig Build System</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<!-- Highly compressed 32x32 Zig logo -->
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABSklEQVRYw8WWXbLDIAiFP5xuURYpi+Q+VDvJTYxaY8pLJ52EA5zDj/AD8wRABCw8DeyJBDiAKMiDGaecNYCKYgCvh4EBjPgGh0UVqAB/MEU3D57efDRMiRhWddprCljRAECPCE0Uw4iz4Jn3tP2zFYAB6on4/8NBM1Es+9kl0aKgaMRnwHPpT5MIDb6YzLzp57wNIyIC7iCCdijeL3gv78jZe6cVENn/drRbXbxl4lXSmB3FtbY0iNrjIEwMm6u2VFFjWQCN0qtov6+wANxG/IV7eR8DHw6gzft4NuEXvA8HcDfv31SgyvsMeDUA90/WTd47bsCdv8PUrWzDyw02uIYv13ktgOVr+IqCouila7gWgNYuly/BfVSEdsP5Vdqyiz7pPC40C+p2e21bL5/dByGtAD6eZPuzeznwjoIN748BfyqwmVDyJHCxPwLSkjUkraEXAAAAAElFTkSuQmCC">
|
||||
|
||||
<!-- Templates, to be cloned into shadow DOMs by JavaScript -->
|
||||
|
||||
<template id="timeReportEntryTemplate">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="time_report.css">
|
||||
<details>
|
||||
<summary><slot name="step-name"></slot></summary>
|
||||
<div id="genericReport">
|
||||
<div class="stats">
|
||||
Time: <slot name="stat-total-time"></slot><br>
|
||||
</div>
|
||||
</div>
|
||||
<div id="compileReport">
|
||||
<div class="stats">
|
||||
Files Discovered: <slot name="stat-reachable-files"></slot><br>
|
||||
Files Analyzed: <slot name="stat-imported-files"></slot><br>
|
||||
Generic Instances Analyzed: <slot name="stat-generic-instances"></slot><br>
|
||||
Inline Calls Analyzed: <slot name="stat-inline-calls"></slot><br>
|
||||
Compilation Time: <slot name="stat-compilation-time"></slot><br>
|
||||
</div>
|
||||
<table class="time-stats">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Pipeline Component</th>
|
||||
<th scope="col" class="tooltip">CPU Time
|
||||
<span class="tooltip-content">Sum across all threads of the time spent in this pipeline component</span>
|
||||
</th>
|
||||
<th scope="col" class="tooltip">Real Time
|
||||
<span class="tooltip-content">Wall-clock time elapsed between the start and end of this compilation phase</span>
|
||||
</th>
|
||||
<th scope="col">Compilation Phase</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" class="tooltip">Parsing
|
||||
<span class="tooltip-content"><code>tokenize</code> converts a file of Zig source code into a sequence of tokens, which are then processed by <code>Parse</code> into an Abstract Syntax Tree (AST).</span>
|
||||
</th>
|
||||
<td><slot name="cpu-time-parse"></slot></td>
|
||||
<td rowspan="2"><slot name="real-time-files"></slot></td>
|
||||
<th scope="row" rowspan="2" class="tooltip">File Lower
|
||||
<span class="tooltip-content">Tokenization, parsing, and lowering of Zig source files to a high-level IR.<br><br>Starting from module roots, every file theoretically accessible through a chain of <code>@import</code> calls is processed. Individual source files are processed serially, but different files are processed in parallel by a thread pool.<br><br>The results of this phase of compilation are cached on disk per source file, meaning the time spent here is typically only relevant to "clean" builds.</span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="tooltip">AST Lowering
|
||||
<span class="tooltip-content"><code>AstGen</code> converts a file's AST into a high-level SSA IR named Zig Intermediate Representation (ZIR). The resulting ZIR code is cached on disk to avoid, for instance, re-lowering all source files in the Zig standard library each time the compiler is invoked.</span>
|
||||
</th>
|
||||
<td><slot name="cpu-time-astgen"></slot></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="tooltip">Semantic Analysis
|
||||
<span class="tooltip-content"><code>Sema</code> interprets ZIR to perform type checking, compile-time code execution, and type resolution, collectively termed "semantic analysis". When a runtime function body is analyzed, it emits Analyzed Intermediate Representation (AIR) code to be sent to the next pipeline component. Semantic analysis is currently entirely single-threaded.</span>
|
||||
</th>
|
||||
<td><slot name="cpu-time-sema"></slot></td>
|
||||
<td rowspan="3"><slot name="real-time-decls"></slot></td>
|
||||
<th scope="row" rowspan="3" class="tooltip">Declaration Lower
|
||||
<span class="tooltip-content">Semantic analysis, code generation, and linking, at the granularity of individual declarations (as opposed to whole source files).<br><br>These components are run in parallel with one another. Semantic analysis is almost always the bottleneck, as it is complex and currently can only run single-threaded.<br><br>This phase completes when a work queue empties, but semantic analysis may add work by one declaration referencing another.<br><br>This is the main phase of compilation, typically taking significantly longer than File Lower (even in a clean build).</span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="tooltip">Code Generation
|
||||
<span class="tooltip-content"><code>CodeGen</code> converts AIR from <code>Sema</code> into machine instructions in the form of Machine Intermediate Representation (MIR). This work is usually highly parallel, since in most cases, arbitrarily many functions can be run through <code>CodeGen</code> simultaneously.</span>
|
||||
</th>
|
||||
<td><slot name="cpu-time-codegen"></slot></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="tooltip">Linking
|
||||
<span class="tooltip-content"><code>link</code> converts MIR from <code>CodeGen</code>, as well as global constants and variables from <code>Sema</code>, and places them in the output binary. MIR is converted to a finished sequence of real instruction bytes.<br><br>When using the LLVM backend, most of this work is instead deferred to the "LLVM Emit" phase.</span>
|
||||
</th>
|
||||
<td><slot name="cpu-time-link"></slot></td>
|
||||
</tr>
|
||||
<tr class="llvm-only">
|
||||
<th class="empty-cell"></th>
|
||||
<td class="empty-cell"></td>
|
||||
<td><slot name="real-time-llvm-emit"></slot></td>
|
||||
<th scope="row" class="tooltip">LLVM Emit
|
||||
<span class="tooltip-content"><b>Only applicable when using the LLVM backend.</b><br><br>Conversion of generated LLVM bitcode to an object file, including any optimization passes.<br><br>When using LLVM, this phase of compilation is typically the slowest by a significant margin. Unfortunately, the Zig compiler implementation has essentially no control over it.</span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="empty-cell"></th>
|
||||
<td class="empty-cell"></td>
|
||||
<td><slot name="real-time-link-flush"></slot></td>
|
||||
<th scope="row" class="tooltip">Linker Flush
|
||||
<span class="tooltip-content">Finalizing the emitted binary, and ensuring it is fully written to disk.<br><br>When using LLD, this phase represents the entire linker invocation. Otherwise, the amount of work performed here is dependent on details of Zig's linker implementation for the particular output format, but typically aims to be fairly minimal.</span>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<details class="section">
|
||||
<summary>Files</summary>
|
||||
<table class="time-stats">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">File</th>
|
||||
<th scope="col">Semantic Analysis</th>
|
||||
<th scope="col">Code Generation</th>
|
||||
<th scope="col">Linking</th>
|
||||
<th scope="col">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- HTML does not allow placing a 'slot' inside of a 'tbody' for backwards-compatibility
|
||||
reasons, so we unfortunately must template on the `id` here. -->
|
||||
<tbody id="fileTableBody"></tbody>
|
||||
</table>
|
||||
</details>
|
||||
<details class="section">
|
||||
<summary>Declarations</summary>
|
||||
<table class="time-stats">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">File</th>
|
||||
<th scope="col">Declaration</th>
|
||||
<th scope="col" class="tooltip">Analysis Count
|
||||
<span class="tooltip-content">The number of times the compiler analyzed some part of this declaration. If this is a function, <code>inline</code> and <code>comptime</code> calls to it are <i>not</i> included here. Typically, this value is approximately equal to the number of instances of a generic declaration.</span>
|
||||
</th>
|
||||
<th scope="col">Semantic Analysis</th>
|
||||
<th scope="col">Code Generation</th>
|
||||
<th scope="col">Linking</th>
|
||||
<th scope="col">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- HTML does not allow placing a 'slot' inside of a 'tbody' for backwards-compatibility
|
||||
reasons, so we unfortunately must template on the `id` here. -->
|
||||
<tbody id="declTableBody"></tbody>
|
||||
</table>
|
||||
</details>
|
||||
<details class="section llvm-only">
|
||||
<summary>LLVM Pass Timings</summary>
|
||||
<div><slot name="llvm-pass-timings"></slot></div>
|
||||
</details>
|
||||
</div>
|
||||
<div id="runTestReport">
|
||||
<table class="time-stats">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Test Name</th>
|
||||
<th scope="col">Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- HTML does not allow placing a 'slot' inside of a 'tbody' for backwards-compatibility
|
||||
reasons, so we unfortunately must template on the `id` here. -->
|
||||
<tbody id="runTestTableBody"></tbody>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</template>
|
||||
|
||||
<template id="fuzzEntryTemplate">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<ul>
|
||||
<li>Total Runs: <slot name="stat-total-runs"></slot></li>
|
||||
<li>Unique Runs: <slot name="stat-unique-runs"></slot></li>
|
||||
<li>Speed: <slot name="stat-speed"></slot> runs/sec</li>
|
||||
<li>Coverage: <slot name="stat-coverage"></slot></li>
|
||||
</ul>
|
||||
<!-- I have observed issues in Firefox clicking frequently-updating slotted links, so the entry
|
||||
point list is handled separately since it rarely changes. -->
|
||||
<ul id="entryPointList" class="no-marker"></ul>
|
||||
<div id="source" class="hidden">
|
||||
<h2>Source Code</h2>
|
||||
<pre><code id="sourceText"></code></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- The actual body: fairly minimal, content populated by JavaScript -->
|
||||
|
||||
<p id="connectionStatus">Loading JavaScript...</p>
|
||||
<p class="hidden" id="firefoxWebSocketBullshitExplainer">
|
||||
If you are using Firefox and <code>zig build --listen</code> is definitely running, you may be experiencing an unreasonably aggressive exponential
|
||||
backoff for WebSocket connection attempts, which is enabled by default and can block connection attempts for up to a minute. To disable this limit,
|
||||
open <code>about:config</code> and set the <code>network.websocket.delay-failed-reconnects</code> option to <code>false</code>.
|
||||
</p>
|
||||
<main class="hidden">
|
||||
<h1>Zig Build System</h1>
|
||||
|
||||
<p><span id="summaryStatus"></span> | <span id="summaryStepCount"></span> steps</p>
|
||||
<button class="big-btn" id="buttonRebuild" disabled>Rebuild</button>
|
||||
|
||||
<ul class="no-marker" id="stepList"></ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="timeReport" class="hidden">
|
||||
<h1>Time Report</h1>
|
||||
<div id="timeReportList"></div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div id="fuzz" class="hidden">
|
||||
<h1>Fuzzer</h1>
|
||||
<p id="fuzzStatus"></p>
|
||||
<div id="fuzzEntries"></div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<h1>Help</h1>
|
||||
<p>This is the Zig Build System web interface. It allows live interaction with the build system.</p>
|
||||
<p>The following <code>zig build</code> flags can expose extra features of this interface:</p>
|
||||
<ul>
|
||||
<li><code>--time-report</code>: collect and show statistics about the time taken to evaluate a build graph</li>
|
||||
<li><code>--fuzz</code>: enable the fuzzer for any Zig test binaries in the build graph (experimental)</li>
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<!-- JavaScript at the very end -->
|
||||
|
||||
<script src="main.js"></script>
|
||||
@ -1,366 +0,0 @@
|
||||
const domConnectionStatus = document.getElementById("connectionStatus");
|
||||
const domFirefoxWebSocketBullshitExplainer = document.getElementById("firefoxWebSocketBullshitExplainer");
|
||||
|
||||
const domMain = document.getElementsByTagName("main")[0];
|
||||
const domSummary = {
|
||||
stepCount: document.getElementById("summaryStepCount"),
|
||||
status: document.getElementById("summaryStatus"),
|
||||
};
|
||||
const domButtonRebuild = document.getElementById("buttonRebuild");
|
||||
const domStepList = document.getElementById("stepList");
|
||||
let domSteps = [];
|
||||
|
||||
let wasm_promise = fetch("main.wasm");
|
||||
let wasm_exports = null;
|
||||
|
||||
const text_decoder = new TextDecoder();
|
||||
const text_encoder = new TextEncoder();
|
||||
|
||||
domButtonRebuild.addEventListener("click", () => wasm_exports.rebuild());
|
||||
|
||||
setConnectionStatus("Loading WebAssembly...", false);
|
||||
WebAssembly.instantiateStreaming(wasm_promise, {
|
||||
core: {
|
||||
log: function(ptr, len) {
|
||||
const msg = decodeString(ptr, len);
|
||||
console.log(msg);
|
||||
},
|
||||
panic: function (ptr, len) {
|
||||
const msg = decodeString(ptr, len);
|
||||
throw new Error("panic: " + msg);
|
||||
},
|
||||
timestamp: function () {
|
||||
return BigInt(new Date());
|
||||
},
|
||||
hello: hello,
|
||||
updateBuildStatus: updateBuildStatus,
|
||||
updateStepStatus: updateStepStatus,
|
||||
sendWsMessage: (ptr, len) => ws.send(new Uint8Array(wasm_exports.memory.buffer, ptr, len)),
|
||||
},
|
||||
fuzz: {
|
||||
requestSources: fuzzRequestSources,
|
||||
ready: fuzzReady,
|
||||
updateStats: fuzzUpdateStats,
|
||||
updateEntryPoints: fuzzUpdateEntryPoints,
|
||||
updateSource: fuzzUpdateSource,
|
||||
updateCoverage: fuzzUpdateCoverage,
|
||||
},
|
||||
time_report: {
|
||||
updateGeneric: timeReportUpdateGeneric,
|
||||
updateCompile: timeReportUpdateCompile,
|
||||
updateRunTest: timeReportUpdateRunTest,
|
||||
},
|
||||
}).then(function(obj) {
|
||||
setConnectionStatus("Connecting to WebSocket...", true);
|
||||
connectWebSocket();
|
||||
|
||||
wasm_exports = obj.instance.exports;
|
||||
window.wasm = obj; // for debugging
|
||||
});
|
||||
|
||||
function connectWebSocket() {
|
||||
const host = document.location.host;
|
||||
const pathname = document.location.pathname;
|
||||
const isHttps = document.location.protocol === 'https:';
|
||||
const match = host.match(/^(.+):(\d+)$/);
|
||||
const defaultPort = isHttps ? 443 : 80;
|
||||
const port = match ? parseInt(match[2], 10) : defaultPort;
|
||||
const hostName = match ? match[1] : host;
|
||||
const wsProto = isHttps ? "wss:" : "ws:";
|
||||
const wsUrl = wsProto + '//' + hostName + ':' + port + pathname;
|
||||
ws = new WebSocket(wsUrl);
|
||||
ws.binaryType = "arraybuffer";
|
||||
ws.addEventListener('message', onWebSocketMessage, false);
|
||||
ws.addEventListener('error', onWebSocketClose, false);
|
||||
ws.addEventListener('close', onWebSocketClose, false);
|
||||
ws.addEventListener('open', onWebSocketOpen, false);
|
||||
}
|
||||
function onWebSocketOpen() {
|
||||
setConnectionStatus("Waiting for data...", false);
|
||||
}
|
||||
function onWebSocketMessage(ev) {
|
||||
const jsArray = new Uint8Array(ev.data);
|
||||
const ptr = wasm_exports.message_begin(jsArray.length);
|
||||
const wasmArray = new Uint8Array(wasm_exports.memory.buffer, ptr, jsArray.length);
|
||||
wasmArray.set(jsArray);
|
||||
wasm_exports.message_end();
|
||||
}
|
||||
function onWebSocketClose() {
|
||||
setConnectionStatus("WebSocket connection closed. Re-connecting...", true);
|
||||
ws.removeEventListener('message', onWebSocketMessage, false);
|
||||
ws.removeEventListener('error', onWebSocketClose, false);
|
||||
ws.removeEventListener('close', onWebSocketClose, false);
|
||||
ws.removeEventListener('open', onWebSocketOpen, false);
|
||||
ws = null;
|
||||
setTimeout(connectWebSocket, 1000);
|
||||
}
|
||||
|
||||
function setConnectionStatus(msg, is_websocket_connect) {
|
||||
domConnectionStatus.textContent = msg;
|
||||
if (msg.length > 0) {
|
||||
domConnectionStatus.classList.remove("hidden");
|
||||
domMain.classList.add("hidden");
|
||||
} else {
|
||||
domConnectionStatus.classList.add("hidden");
|
||||
domMain.classList.remove("hidden");
|
||||
}
|
||||
if (is_websocket_connect) {
|
||||
domFirefoxWebSocketBullshitExplainer.classList.remove("hidden");
|
||||
} else {
|
||||
domFirefoxWebSocketBullshitExplainer.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function hello(
|
||||
steps_len,
|
||||
build_status,
|
||||
time_report,
|
||||
) {
|
||||
domSummary.stepCount.textContent = steps_len;
|
||||
updateBuildStatus(build_status);
|
||||
setConnectionStatus("", false);
|
||||
|
||||
{
|
||||
let entries = [];
|
||||
for (let i = 0; i < steps_len; i += 1) {
|
||||
const step_name = unwrapString(wasm_exports.stepName(i));
|
||||
const code = document.createElement("code");
|
||||
code.textContent = step_name;
|
||||
const li = document.createElement("li");
|
||||
li.appendChild(code);
|
||||
entries.push(li);
|
||||
}
|
||||
domStepList.replaceChildren(...entries);
|
||||
for (let i = 0; i < steps_len; i += 1) {
|
||||
updateStepStatus(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (time_report) timeReportReset(steps_len);
|
||||
fuzzReset();
|
||||
}
|
||||
|
||||
function updateBuildStatus(s) {
|
||||
let text;
|
||||
let active = false;
|
||||
let reset_time_reports = false;
|
||||
if (s == 0) {
|
||||
text = "Idle";
|
||||
} else if (s == 1) {
|
||||
text = "Watching for changes...";
|
||||
} else if (s == 2) {
|
||||
text = "Running...";
|
||||
active = true;
|
||||
reset_time_reports = true;
|
||||
} else if (s == 3) {
|
||||
text = "Starting fuzzer...";
|
||||
active = true;
|
||||
} else {
|
||||
console.log(`bad build status: ${s}`);
|
||||
}
|
||||
domSummary.status.textContent = text;
|
||||
if (active) {
|
||||
domSummary.status.classList.add("status-running");
|
||||
domSummary.status.classList.remove("status-idle");
|
||||
domButtonRebuild.disabled = true;
|
||||
} else {
|
||||
domSummary.status.classList.remove("status-running");
|
||||
domSummary.status.classList.add("status-idle");
|
||||
domButtonRebuild.disabled = false;
|
||||
}
|
||||
if (reset_time_reports) {
|
||||
// Grey out and collapse all the time reports
|
||||
for (const time_report_host of domTimeReportList.children) {
|
||||
const details = time_report_host.shadowRoot.querySelector(":host > details");
|
||||
details.classList.add("pending");
|
||||
details.open = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
function updateStepStatus(step_idx) {
|
||||
const li = domStepList.children[step_idx];
|
||||
const step_status = wasm_exports.stepStatus(step_idx);
|
||||
li.classList.remove("step-wip", "step-success", "step-failure");
|
||||
if (step_status == 0) {
|
||||
// pending
|
||||
} else if (step_status == 1) {
|
||||
li.classList.add("step-wip");
|
||||
} else if (step_status == 2) {
|
||||
li.classList.add("step-success");
|
||||
} else if (step_status == 3) {
|
||||
li.classList.add("step-failure");
|
||||
} else {
|
||||
console.log(`bad step status: ${step_status}`);
|
||||
}
|
||||
}
|
||||
|
||||
function decodeString(ptr, len) {
|
||||
if (len === 0) return "";
|
||||
return text_decoder.decode(new Uint8Array(wasm_exports.memory.buffer, ptr, len));
|
||||
}
|
||||
function getU32Array(ptr, len) {
|
||||
if (len === 0) return new Uint32Array();
|
||||
return new Uint32Array(wasm_exports.memory.buffer, ptr, len);
|
||||
}
|
||||
function unwrapString(bigint) {
|
||||
const ptr = Number(bigint & 0xffffffffn);
|
||||
const len = Number(bigint >> 32n);
|
||||
return decodeString(ptr, len);
|
||||
}
|
||||
|
||||
const time_report_entry_template = document.getElementById("timeReportEntryTemplate").content;
|
||||
const domTimeReport = document.getElementById("timeReport");
|
||||
const domTimeReportList = document.getElementById("timeReportList");
|
||||
function timeReportReset(steps_len) {
|
||||
let entries = [];
|
||||
for (let i = 0; i < steps_len; i += 1) {
|
||||
const step_name = unwrapString(wasm_exports.stepName(i));
|
||||
const host = document.createElement("div");
|
||||
const shadow = host.attachShadow({ mode: "open" });
|
||||
shadow.appendChild(time_report_entry_template.cloneNode(true));
|
||||
shadow.querySelector(":host > details").classList.add("pending");
|
||||
const slotted_name = document.createElement("code");
|
||||
slotted_name.setAttribute("slot", "step-name");
|
||||
slotted_name.textContent = step_name;
|
||||
host.appendChild(slotted_name);
|
||||
entries.push(host);
|
||||
}
|
||||
domTimeReportList.replaceChildren(...entries);
|
||||
domTimeReport.classList.remove("hidden");
|
||||
}
|
||||
function timeReportUpdateCompile(
|
||||
step_idx,
|
||||
inner_html_ptr,
|
||||
inner_html_len,
|
||||
file_table_html_ptr,
|
||||
file_table_html_len,
|
||||
decl_table_html_ptr,
|
||||
decl_table_html_len,
|
||||
use_llvm,
|
||||
) {
|
||||
const inner_html = decodeString(inner_html_ptr, inner_html_len);
|
||||
const file_table_html = decodeString(file_table_html_ptr, file_table_html_len);
|
||||
const decl_table_html = decodeString(decl_table_html_ptr, decl_table_html_len);
|
||||
|
||||
const host = domTimeReportList.children.item(step_idx);
|
||||
const shadow = host.shadowRoot;
|
||||
|
||||
shadow.querySelector(":host > details").classList.remove("pending", "no-llvm");
|
||||
|
||||
shadow.getElementById("genericReport").classList.add("hidden");
|
||||
shadow.getElementById("compileReport").classList.remove("hidden");
|
||||
shadow.getElementById("runTestReport").classList.add("hidden");
|
||||
|
||||
if (!use_llvm) shadow.querySelector(":host > details").classList.add("no-llvm");
|
||||
host.innerHTML = inner_html;
|
||||
shadow.getElementById("fileTableBody").innerHTML = file_table_html;
|
||||
shadow.getElementById("declTableBody").innerHTML = decl_table_html;
|
||||
}
|
||||
function timeReportUpdateGeneric(
|
||||
step_idx,
|
||||
inner_html_ptr,
|
||||
inner_html_len,
|
||||
) {
|
||||
const inner_html = decodeString(inner_html_ptr, inner_html_len);
|
||||
const host = domTimeReportList.children.item(step_idx);
|
||||
const shadow = host.shadowRoot;
|
||||
shadow.querySelector(":host > details").classList.remove("pending", "no-llvm");
|
||||
shadow.getElementById("genericReport").classList.remove("hidden");
|
||||
shadow.getElementById("compileReport").classList.add("hidden");
|
||||
shadow.getElementById("runTestReport").classList.add("hidden");
|
||||
host.innerHTML = inner_html;
|
||||
}
|
||||
function timeReportUpdateRunTest(
|
||||
step_idx,
|
||||
table_html_ptr,
|
||||
table_html_len,
|
||||
) {
|
||||
const table_html = decodeString(table_html_ptr, table_html_len);
|
||||
const host = domTimeReportList.children.item(step_idx);
|
||||
const shadow = host.shadowRoot;
|
||||
|
||||
shadow.querySelector(":host > details").classList.remove("pending", "no-llvm");
|
||||
|
||||
shadow.getElementById("genericReport").classList.add("hidden");
|
||||
shadow.getElementById("compileReport").classList.add("hidden");
|
||||
shadow.getElementById("runTestReport").classList.remove("hidden");
|
||||
|
||||
shadow.getElementById("runTestTableBody").innerHTML = table_html;
|
||||
}
|
||||
|
||||
const fuzz_entry_template = document.getElementById("fuzzEntryTemplate").content;
|
||||
const domFuzz = document.getElementById("fuzz");
|
||||
const domFuzzStatus = document.getElementById("fuzzStatus");
|
||||
const domFuzzEntries = document.getElementById("fuzzEntries");
|
||||
let domFuzzInstance = null;
|
||||
function fuzzRequestSources() {
|
||||
domFuzzStatus.classList.remove("hidden");
|
||||
domFuzzStatus.textContent = "Loading sources tarball...";
|
||||
fetch("sources.tar").then(function(response) {
|
||||
if (!response.ok) throw new Error("unable to download sources");
|
||||
domFuzzStatus.textContent = "Parsing fuzz test sources...";
|
||||
return response.arrayBuffer();
|
||||
}).then(function(buffer) {
|
||||
if (buffer.length === 0) throw new Error("sources.tar was empty");
|
||||
const js_array = new Uint8Array(buffer);
|
||||
const ptr = wasm_exports.alloc(js_array.length);
|
||||
const wasm_array = new Uint8Array(wasm_exports.memory.buffer, ptr, js_array.length);
|
||||
wasm_array.set(js_array);
|
||||
wasm_exports.fuzzUnpackSources(ptr, js_array.length);
|
||||
domFuzzStatus.textContent = "";
|
||||
domFuzzStatus.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
function fuzzReady() {
|
||||
domFuzz.classList.remove("hidden");
|
||||
|
||||
// TODO: multiple fuzzer instances
|
||||
if (domFuzzInstance !== null) return;
|
||||
|
||||
const host = document.createElement("div");
|
||||
const shadow = host.attachShadow({ mode: "open" });
|
||||
shadow.appendChild(fuzz_entry_template.cloneNode(true));
|
||||
|
||||
domFuzzInstance = host;
|
||||
domFuzzEntries.appendChild(host);
|
||||
}
|
||||
function fuzzReset() {
|
||||
domFuzz.classList.add("hidden");
|
||||
domFuzzEntries.replaceChildren();
|
||||
domFuzzInstance = null;
|
||||
}
|
||||
function fuzzUpdateStats(stats_html_ptr, stats_html_len) {
|
||||
if (domFuzzInstance === null) throw new Error("fuzzUpdateStats called when fuzzer inactive");
|
||||
const stats_html = decodeString(stats_html_ptr, stats_html_len);
|
||||
const host = domFuzzInstance;
|
||||
host.innerHTML = stats_html;
|
||||
}
|
||||
function fuzzUpdateEntryPoints(entry_points_html_ptr, entry_points_html_len) {
|
||||
if (domFuzzInstance === null) throw new Error("fuzzUpdateEntryPoints called when fuzzer inactive");
|
||||
const entry_points_html = decodeString(entry_points_html_ptr, entry_points_html_len);
|
||||
const domEntryPointList = domFuzzInstance.shadowRoot.getElementById("entryPointList");
|
||||
domEntryPointList.innerHTML = entry_points_html;
|
||||
}
|
||||
function fuzzUpdateSource(source_html_ptr, source_html_len) {
|
||||
if (domFuzzInstance === null) throw new Error("fuzzUpdateSource called when fuzzer inactive");
|
||||
const source_html = decodeString(source_html_ptr, source_html_len);
|
||||
const domSourceText = domFuzzInstance.shadowRoot.getElementById("sourceText");
|
||||
domSourceText.innerHTML = source_html;
|
||||
domFuzzInstance.shadowRoot.getElementById("source").classList.remove("hidden");
|
||||
}
|
||||
function fuzzUpdateCoverage(covered_ptr, covered_len) {
|
||||
if (domFuzzInstance === null) throw new Error("fuzzUpdateCoverage called when fuzzer inactive");
|
||||
const shadow = domFuzzInstance.shadowRoot;
|
||||
const domSourceText = shadow.getElementById("sourceText");
|
||||
const covered = getU32Array(covered_ptr, covered_len);
|
||||
for (let i = 0; i < domSourceText.children.length; i += 1) {
|
||||
const childDom = domSourceText.children[i];
|
||||
if (childDom.id != null && childDom.id[0] == "l") {
|
||||
childDom.classList.add("l");
|
||||
childDom.classList.remove("c");
|
||||
}
|
||||
}
|
||||
for (const sli of covered) {
|
||||
shadow.getElementById(`l${sli}`).classList.add("c");
|
||||
}
|
||||
}
|
||||
@ -1,214 +0,0 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const abi = std.Build.abi;
|
||||
const gpa = std.heap.wasm_allocator;
|
||||
const log = std.log;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const fuzz = @import("fuzz.zig");
|
||||
const time_report = @import("time_report.zig");
|
||||
|
||||
/// Nanoseconds.
|
||||
var server_base_timestamp: i64 = 0;
|
||||
/// Milliseconds.
|
||||
var client_base_timestamp: i64 = 0;
|
||||
|
||||
pub var step_list: []Step = &.{};
|
||||
/// Not accessed after initialization, but must be freed alongside `step_list`.
|
||||
pub var step_list_data: []u8 = &.{};
|
||||
|
||||
const Step = struct {
|
||||
name: []const u8,
|
||||
status: abi.StepUpdate.Status,
|
||||
};
|
||||
|
||||
const js = struct {
|
||||
extern "core" fn log(ptr: [*]const u8, len: usize) void;
|
||||
extern "core" fn panic(ptr: [*]const u8, len: usize) noreturn;
|
||||
extern "core" fn timestamp() i64;
|
||||
extern "core" fn hello(
|
||||
steps_len: u32,
|
||||
status: abi.BuildStatus,
|
||||
time_report: bool,
|
||||
) void;
|
||||
extern "core" fn updateBuildStatus(status: abi.BuildStatus) void;
|
||||
extern "core" fn updateStepStatus(step_idx: u32) void;
|
||||
extern "core" fn sendWsMessage(ptr: [*]const u8, len: usize) void;
|
||||
};
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = logFn,
|
||||
};
|
||||
|
||||
pub fn panic(msg: []const u8, st: ?*std.builtin.StackTrace, addr: ?usize) noreturn {
|
||||
_ = st;
|
||||
_ = addr;
|
||||
log.err("panic: {s}", .{msg});
|
||||
@trap();
|
||||
}
|
||||
|
||||
fn logFn(
|
||||
comptime message_level: log.Level,
|
||||
comptime scope: @EnumLiteral(),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
const level_txt = comptime message_level.asText();
|
||||
const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
||||
var buf: [500]u8 = undefined;
|
||||
const line = std.fmt.bufPrint(&buf, level_txt ++ prefix2 ++ format, args) catch l: {
|
||||
buf[buf.len - 3 ..][0..3].* = "...".*;
|
||||
break :l &buf;
|
||||
};
|
||||
js.log(line.ptr, line.len);
|
||||
}
|
||||
|
||||
export fn alloc(n: usize) [*]u8 {
|
||||
const slice = gpa.alloc(u8, n) catch @panic("OOM");
|
||||
return slice.ptr;
|
||||
}
|
||||
|
||||
var message_buffer: std.ArrayListAlignedUnmanaged(u8, .of(u64)) = .empty;
|
||||
|
||||
/// Resizes the message buffer to be the correct length; returns the pointer to
|
||||
/// the query string.
|
||||
export fn message_begin(len: usize) [*]u8 {
|
||||
message_buffer.resize(gpa, len) catch @panic("OOM");
|
||||
return message_buffer.items.ptr;
|
||||
}
|
||||
|
||||
export fn message_end() void {
|
||||
const msg_bytes = message_buffer.items;
|
||||
|
||||
const tag: abi.ToClientTag = @enumFromInt(msg_bytes[0]);
|
||||
switch (tag) {
|
||||
_ => @panic("malformed message"),
|
||||
|
||||
.hello => return helloMessage(msg_bytes) catch @panic("OOM"),
|
||||
.status_update => return statusUpdateMessage(msg_bytes) catch @panic("OOM"),
|
||||
.step_update => return stepUpdateMessage(msg_bytes) catch @panic("OOM"),
|
||||
|
||||
.fuzz_source_index => return fuzz.sourceIndexMessage(msg_bytes) catch @panic("OOM"),
|
||||
.fuzz_coverage_update => return fuzz.coverageUpdateMessage(msg_bytes) catch @panic("OOM"),
|
||||
.fuzz_entry_points => return fuzz.entryPointsMessage(msg_bytes) catch @panic("OOM"),
|
||||
|
||||
.time_report_generic_result => return time_report.genericResultMessage(msg_bytes) catch @panic("OOM"),
|
||||
.time_report_compile_result => return time_report.compileResultMessage(msg_bytes) catch @panic("OOM"),
|
||||
.time_report_run_test_result => return time_report.runTestResultMessage(msg_bytes) catch @panic("OOM"),
|
||||
}
|
||||
}
|
||||
|
||||
const String = Slice(u8);
|
||||
|
||||
pub fn Slice(T: type) type {
|
||||
return packed struct(u64) {
|
||||
ptr: u32,
|
||||
len: u32,
|
||||
|
||||
pub fn init(s: []const T) @This() {
|
||||
return .{
|
||||
.ptr = @intFromPtr(s.ptr),
|
||||
.len = s.len,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
|
||||
var buf: [500]u8 = undefined;
|
||||
const line = std.fmt.bufPrint(&buf, format, args) catch l: {
|
||||
buf[buf.len - 3 ..][0..3].* = "...".*;
|
||||
break :l &buf;
|
||||
};
|
||||
js.panic(line.ptr, line.len);
|
||||
}
|
||||
|
||||
fn helloMessage(msg_bytes: []align(4) u8) Allocator.Error!void {
|
||||
if (msg_bytes.len < @sizeOf(abi.Hello)) @panic("malformed Hello message");
|
||||
const hdr: *const abi.Hello = @ptrCast(msg_bytes[0..@sizeOf(abi.Hello)]);
|
||||
const trailing = msg_bytes[@sizeOf(abi.Hello)..];
|
||||
|
||||
client_base_timestamp = js.timestamp();
|
||||
server_base_timestamp = hdr.timestamp;
|
||||
|
||||
const steps = try gpa.alloc(Step, hdr.steps_len);
|
||||
errdefer gpa.free(steps);
|
||||
|
||||
const step_name_lens: []align(1) const u32 = @ptrCast(trailing[0 .. steps.len * 4]);
|
||||
|
||||
const step_name_data_len: usize = len: {
|
||||
var sum: usize = 0;
|
||||
for (step_name_lens) |n| sum += n;
|
||||
break :len sum;
|
||||
};
|
||||
const step_name_data: []const u8 = trailing[steps.len * 4 ..][0..step_name_data_len];
|
||||
const step_status_bits: []const u8 = trailing[steps.len * 4 + step_name_data_len ..];
|
||||
|
||||
const duped_step_name_data = try gpa.dupe(u8, step_name_data);
|
||||
errdefer gpa.free(duped_step_name_data);
|
||||
|
||||
var name_off: usize = 0;
|
||||
for (steps, step_name_lens, 0..) |*step_out, name_len, step_idx| {
|
||||
step_out.* = .{
|
||||
.name = duped_step_name_data[name_off..][0..name_len],
|
||||
.status = @enumFromInt(@as(u2, @truncate(step_status_bits[step_idx / 4] >> @intCast((step_idx % 4) * 2)))),
|
||||
};
|
||||
name_off += name_len;
|
||||
}
|
||||
|
||||
gpa.free(step_list);
|
||||
gpa.free(step_list_data);
|
||||
step_list = steps;
|
||||
step_list_data = duped_step_name_data;
|
||||
|
||||
js.hello(step_list.len, hdr.status, hdr.flags.time_report);
|
||||
}
|
||||
fn statusUpdateMessage(msg_bytes: []u8) Allocator.Error!void {
|
||||
if (msg_bytes.len < @sizeOf(abi.StatusUpdate)) @panic("malformed StatusUpdate message");
|
||||
const msg: *const abi.StatusUpdate = @ptrCast(msg_bytes[0..@sizeOf(abi.StatusUpdate)]);
|
||||
js.updateBuildStatus(msg.new);
|
||||
}
|
||||
fn stepUpdateMessage(msg_bytes: []u8) Allocator.Error!void {
|
||||
if (msg_bytes.len < @sizeOf(abi.StepUpdate)) @panic("malformed StepUpdate message");
|
||||
const msg: *const abi.StepUpdate = @ptrCast(msg_bytes[0..@sizeOf(abi.StepUpdate)]);
|
||||
if (msg.step_idx >= step_list.len) @panic("malformed StepUpdate message");
|
||||
step_list[msg.step_idx].status = msg.bits.status;
|
||||
js.updateStepStatus(msg.step_idx);
|
||||
}
|
||||
|
||||
export fn stepName(idx: usize) String {
|
||||
return .init(step_list[idx].name);
|
||||
}
|
||||
export fn stepStatus(idx: usize) u8 {
|
||||
return @intFromEnum(step_list[idx].status);
|
||||
}
|
||||
|
||||
export fn rebuild() void {
|
||||
const msg: abi.Rebuild = .{};
|
||||
const raw: []const u8 = @ptrCast(&msg);
|
||||
js.sendWsMessage(raw.ptr, raw.len);
|
||||
}
|
||||
|
||||
/// Nanoseconds passed since a server timestamp.
|
||||
pub fn nsSince(server_timestamp: i64) i64 {
|
||||
const ms_passed = js.timestamp() - client_base_timestamp;
|
||||
const ns_passed = server_base_timestamp - server_timestamp;
|
||||
return ns_passed + ms_passed * std.time.ns_per_ms;
|
||||
}
|
||||
|
||||
pub fn fmtEscapeHtml(unescaped: []const u8) HtmlEscaper {
|
||||
return .{ .unescaped = unescaped };
|
||||
}
|
||||
const HtmlEscaper = struct {
|
||||
unescaped: []const u8,
|
||||
pub fn format(he: HtmlEscaper, w: *std.Io.Writer) !void {
|
||||
for (he.unescaped) |c| switch (c) {
|
||||
'&' => try w.writeAll("&"),
|
||||
'<' => try w.writeAll("<"),
|
||||
'>' => try w.writeAll(">"),
|
||||
'"' => try w.writeAll("""),
|
||||
'\'' => try w.writeAll("'"),
|
||||
else => try w.writeByte(c),
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -1,240 +0,0 @@
|
||||
body {
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
color: #000000;
|
||||
padding: 1em 10%;
|
||||
}
|
||||
ul.no-marker {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
hr {
|
||||
margin: 2em 0;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.empty-cell {
|
||||
background: #ccc;
|
||||
}
|
||||
table.time-stats > tbody > tr > th {
|
||||
text-align: left;
|
||||
}
|
||||
table.time-stats > tbody > tr > td {
|
||||
text-align: right;
|
||||
}
|
||||
details > summary {
|
||||
cursor: pointer;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.tooltip {
|
||||
text-decoration: underline;
|
||||
cursor: help;
|
||||
}
|
||||
.tooltip-content {
|
||||
border-radius: 6px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
border: 1px solid black;
|
||||
max-width: 500px;
|
||||
padding: 1em;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
pointer-events: none;
|
||||
}
|
||||
.tooltip:hover > .tooltip-content {
|
||||
display: block;
|
||||
}
|
||||
table {
|
||||
margin: 1.0em auto 1.5em 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th, td {
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
border: 1px solid;
|
||||
border-color: black;
|
||||
}
|
||||
a, button {
|
||||
color: #2A6286;
|
||||
}
|
||||
button {
|
||||
background: #eee;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
padding: 0.2em 0.5em;
|
||||
}
|
||||
button.big-btn {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
button.linkish {
|
||||
background: none;
|
||||
text-decoration: underline;
|
||||
padding: 0;
|
||||
}
|
||||
button:disabled {
|
||||
color: #888;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
pre {
|
||||
font-family: "Source Code Pro", monospace;
|
||||
font-size: 1em;
|
||||
background-color: #F5F5F5;
|
||||
padding: 1em;
|
||||
margin: 0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
:not(pre) > code {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
code {
|
||||
font-family: "Source Code Pro", monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
code a {
|
||||
color: #000000;
|
||||
}
|
||||
kbd {
|
||||
color: #000;
|
||||
background-color: #fafbfc;
|
||||
border-color: #d1d5da;
|
||||
border-bottom-color: #c6cbd1;
|
||||
box-shadow-color: #c6cbd1;
|
||||
display: inline-block;
|
||||
padding: 0.3em 0.2em;
|
||||
font: 1.2em monospace;
|
||||
line-height: 0.8em;
|
||||
vertical-align: middle;
|
||||
border: solid 1px;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.status-running { color: #181; }
|
||||
.status-idle { color: #444; }
|
||||
.step-success { color: #181; }
|
||||
.step-failure { color: #d11; }
|
||||
.step-wip::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
margin-left: -1.5em;
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
animation-name: spinner;
|
||||
animation-duration: 0.5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: step-start;
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% { content: '|'; }
|
||||
25% { content: '/'; }
|
||||
50% { content: '-'; }
|
||||
75% { content: '\\'; }
|
||||
100% { content: '|'; }
|
||||
}
|
||||
|
||||
.l {
|
||||
display: inline-block;
|
||||
background: red;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.c {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #0086b3;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #008080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #008080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #111;
|
||||
color: #ddd;
|
||||
}
|
||||
pre {
|
||||
background-color: #222;
|
||||
}
|
||||
a, button {
|
||||
color: #88f;
|
||||
}
|
||||
button {
|
||||
background: #333;
|
||||
}
|
||||
button:disabled {
|
||||
color: #555;
|
||||
}
|
||||
code a {
|
||||
color: #eee;
|
||||
}
|
||||
th, td {
|
||||
border-color: white;
|
||||
}
|
||||
.empty-cell {
|
||||
background: #000;
|
||||
}
|
||||
.tooltip-content {
|
||||
background: #060606;
|
||||
border-color: white;
|
||||
}
|
||||
.status-running { color: #90ee90; }
|
||||
.status-idle { color: #bbb; }
|
||||
.step-success { color: #90ee90; }
|
||||
.step-failure { color: #f66; }
|
||||
.l {
|
||||
background-color: red;
|
||||
}
|
||||
.c {
|
||||
background-color: green;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
:host > details {
|
||||
padding: 0.5em 1em;
|
||||
background: #f2f2f2;
|
||||
margin-bottom: 1.0em;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
:host > details.pending {
|
||||
pointer-events: none;
|
||||
background: #fafafa;
|
||||
color: #666;
|
||||
}
|
||||
:host > details > div {
|
||||
margin: 1em 2em;
|
||||
overflow: scroll; /* we'll try to avoid overflow, but if it does happen, this makes sense */
|
||||
}
|
||||
.stats {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
details.section {
|
||||
margin: 1.0em 0 0 0;
|
||||
}
|
||||
details.section > summary {
|
||||
font-weight: bold;
|
||||
}
|
||||
details.section > :not(summary) {
|
||||
margin-left: 2em;
|
||||
}
|
||||
:host > details.no-llvm .llvm-only {
|
||||
display: none;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host > details {
|
||||
background: #222;
|
||||
}
|
||||
:host > details.pending {
|
||||
background: #181818;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
th {
|
||||
max-width: 20em; /* don't let the 'file' column get crazy long */
|
||||
overflow-wrap: anywhere; /* avoid overflow where possible */
|
||||
}
|
||||
@ -1,280 +0,0 @@
|
||||
const std = @import("std");
|
||||
const gpa = std.heap.wasm_allocator;
|
||||
const abi = std.Build.abi.time_report;
|
||||
const fmtEscapeHtml = @import("root").fmtEscapeHtml;
|
||||
const step_list = &@import("root").step_list;
|
||||
|
||||
const js = struct {
|
||||
extern "time_report" fn updateGeneric(
|
||||
/// The index of the step.
|
||||
step_idx: u32,
|
||||
// The HTML which will be used to populate the template slots.
|
||||
inner_html_ptr: [*]const u8,
|
||||
inner_html_len: usize,
|
||||
) void;
|
||||
extern "time_report" fn updateCompile(
|
||||
/// The index of the step.
|
||||
step_idx: u32,
|
||||
// The HTML which will be used to populate the template slots.
|
||||
inner_html_ptr: [*]const u8,
|
||||
inner_html_len: usize,
|
||||
// The HTML which will populate the <tbody> of the file table.
|
||||
file_table_html_ptr: [*]const u8,
|
||||
file_table_html_len: usize,
|
||||
// The HTML which will populate the <tbody> of the decl table.
|
||||
decl_table_html_ptr: [*]const u8,
|
||||
decl_table_html_len: usize,
|
||||
/// Whether the LLVM backend was used. If not, LLVM-specific statistics are hidden.
|
||||
use_llvm: bool,
|
||||
) void;
|
||||
extern "time_report" fn updateRunTest(
|
||||
/// The index of the step.
|
||||
step_idx: u32,
|
||||
// The HTML which will populate the <tbody> of the test table.
|
||||
table_html_ptr: [*]const u8,
|
||||
table_html_len: usize,
|
||||
) void;
|
||||
};
|
||||
|
||||
pub fn genericResultMessage(msg_bytes: []u8) error{OutOfMemory}!void {
|
||||
if (msg_bytes.len != @sizeOf(abi.GenericResult)) @panic("malformed GenericResult message");
|
||||
const msg: *const abi.GenericResult = @ptrCast(msg_bytes);
|
||||
if (msg.step_idx >= step_list.*.len) @panic("malformed GenericResult message");
|
||||
const inner_html = try std.fmt.allocPrint(gpa,
|
||||
\\<code slot="step-name">{[step_name]f}</code>
|
||||
\\<span slot="stat-total-time">{[stat_total_time]D}</span>
|
||||
, .{
|
||||
.step_name = fmtEscapeHtml(step_list.*[msg.step_idx].name),
|
||||
.stat_total_time = msg.ns_total,
|
||||
});
|
||||
defer gpa.free(inner_html);
|
||||
js.updateGeneric(msg.step_idx, inner_html.ptr, inner_html.len);
|
||||
}
|
||||
|
||||
pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!void {
|
||||
const max_table_rows = 500;
|
||||
|
||||
if (msg_bytes.len < @sizeOf(abi.CompileResult)) @panic("malformed CompileResult message");
|
||||
const hdr: *const abi.CompileResult = @ptrCast(msg_bytes[0..@sizeOf(abi.CompileResult)]);
|
||||
if (hdr.step_idx >= step_list.*.len) @panic("malformed CompileResult message");
|
||||
var trailing = msg_bytes[@sizeOf(abi.CompileResult)..];
|
||||
|
||||
const llvm_pass_timings = trailing[0..hdr.llvm_pass_timings_len];
|
||||
trailing = trailing[hdr.llvm_pass_timings_len..];
|
||||
|
||||
const FileTimeReport = struct {
|
||||
name: []const u8,
|
||||
ns_sema: u64,
|
||||
ns_codegen: u64,
|
||||
ns_link: u64,
|
||||
};
|
||||
const DeclTimeReport = struct {
|
||||
file_name: []const u8,
|
||||
name: []const u8,
|
||||
sema_count: u32,
|
||||
ns_sema: u64,
|
||||
ns_codegen: u64,
|
||||
ns_link: u64,
|
||||
};
|
||||
|
||||
const slowest_files = try gpa.alloc(FileTimeReport, hdr.files_len);
|
||||
defer gpa.free(slowest_files);
|
||||
|
||||
const slowest_decls = try gpa.alloc(DeclTimeReport, hdr.decls_len);
|
||||
defer gpa.free(slowest_decls);
|
||||
|
||||
for (slowest_files) |*file_out| {
|
||||
const i = std.mem.indexOfScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message");
|
||||
file_out.* = .{
|
||||
.name = trailing[0..i],
|
||||
.ns_sema = 0,
|
||||
.ns_codegen = 0,
|
||||
.ns_link = 0,
|
||||
};
|
||||
trailing = trailing[i + 1 ..];
|
||||
}
|
||||
|
||||
for (slowest_decls) |*decl_out| {
|
||||
const i = std.mem.indexOfScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message");
|
||||
const file_idx = std.mem.readInt(u32, trailing[i..][1..5], .little);
|
||||
const sema_count = std.mem.readInt(u32, trailing[i..][5..9], .little);
|
||||
const sema_ns = std.mem.readInt(u64, trailing[i..][9..17], .little);
|
||||
const codegen_ns = std.mem.readInt(u64, trailing[i..][17..25], .little);
|
||||
const link_ns = std.mem.readInt(u64, trailing[i..][25..33], .little);
|
||||
const file = &slowest_files[file_idx];
|
||||
decl_out.* = .{
|
||||
.file_name = file.name,
|
||||
.name = trailing[0..i],
|
||||
.sema_count = sema_count,
|
||||
.ns_sema = sema_ns,
|
||||
.ns_codegen = codegen_ns,
|
||||
.ns_link = link_ns,
|
||||
};
|
||||
trailing = trailing[i + 33 ..];
|
||||
file.ns_sema += sema_ns;
|
||||
file.ns_codegen += codegen_ns;
|
||||
file.ns_link += link_ns;
|
||||
}
|
||||
|
||||
const S = struct {
|
||||
fn fileLessThan(_: void, lhs: FileTimeReport, rhs: FileTimeReport) bool {
|
||||
const lhs_ns = lhs.ns_sema + lhs.ns_codegen + lhs.ns_link;
|
||||
const rhs_ns = rhs.ns_sema + rhs.ns_codegen + rhs.ns_link;
|
||||
return lhs_ns > rhs_ns; // flipped to sort in reverse order
|
||||
}
|
||||
fn declLessThan(_: void, lhs: DeclTimeReport, rhs: DeclTimeReport) bool {
|
||||
//if (true) return lhs.sema_count > rhs.sema_count;
|
||||
const lhs_ns = lhs.ns_sema + lhs.ns_codegen + lhs.ns_link;
|
||||
const rhs_ns = rhs.ns_sema + rhs.ns_codegen + rhs.ns_link;
|
||||
return lhs_ns > rhs_ns; // flipped to sort in reverse order
|
||||
}
|
||||
};
|
||||
std.mem.sort(FileTimeReport, slowest_files, {}, S.fileLessThan);
|
||||
std.mem.sort(DeclTimeReport, slowest_decls, {}, S.declLessThan);
|
||||
|
||||
const stats = hdr.stats;
|
||||
const inner_html = try std.fmt.allocPrint(gpa,
|
||||
\\<code slot="step-name">{[step_name]f}</code>
|
||||
\\<span slot="stat-reachable-files">{[stat_reachable_files]d}</span>
|
||||
\\<span slot="stat-imported-files">{[stat_imported_files]d}</span>
|
||||
\\<span slot="stat-generic-instances">{[stat_generic_instances]d}</span>
|
||||
\\<span slot="stat-inline-calls">{[stat_inline_calls]d}</span>
|
||||
\\<span slot="stat-compilation-time">{[stat_compilation_time]D}</span>
|
||||
\\<span slot="cpu-time-parse">{[cpu_time_parse]D}</span>
|
||||
\\<span slot="cpu-time-astgen">{[cpu_time_astgen]D}</span>
|
||||
\\<span slot="cpu-time-sema">{[cpu_time_sema]D}</span>
|
||||
\\<span slot="cpu-time-codegen">{[cpu_time_codegen]D}</span>
|
||||
\\<span slot="cpu-time-link">{[cpu_time_link]D}</span>
|
||||
\\<span slot="real-time-files">{[real_time_files]D}</span>
|
||||
\\<span slot="real-time-decls">{[real_time_decls]D}</span>
|
||||
\\<span slot="real-time-llvm-emit">{[real_time_llvm_emit]D}</span>
|
||||
\\<span slot="real-time-link-flush">{[real_time_link_flush]D}</span>
|
||||
\\<pre slot="llvm-pass-timings"><code>{[llvm_pass_timings]f}</code></pre>
|
||||
\\
|
||||
, .{
|
||||
.step_name = fmtEscapeHtml(step_list.*[hdr.step_idx].name),
|
||||
.stat_reachable_files = stats.n_reachable_files,
|
||||
.stat_imported_files = stats.n_imported_files,
|
||||
.stat_generic_instances = stats.n_generic_instances,
|
||||
.stat_inline_calls = stats.n_inline_calls,
|
||||
.stat_compilation_time = hdr.ns_total,
|
||||
|
||||
.cpu_time_parse = stats.cpu_ns_parse,
|
||||
.cpu_time_astgen = stats.cpu_ns_astgen,
|
||||
.cpu_time_sema = stats.cpu_ns_sema,
|
||||
.cpu_time_codegen = stats.cpu_ns_codegen,
|
||||
.cpu_time_link = stats.cpu_ns_link,
|
||||
.real_time_files = stats.real_ns_files,
|
||||
.real_time_decls = stats.real_ns_decls,
|
||||
.real_time_llvm_emit = stats.real_ns_llvm_emit,
|
||||
.real_time_link_flush = stats.real_ns_link_flush,
|
||||
|
||||
.llvm_pass_timings = fmtEscapeHtml(llvm_pass_timings),
|
||||
});
|
||||
defer gpa.free(inner_html);
|
||||
|
||||
var file_table_html: std.Io.Writer.Allocating = .init(gpa);
|
||||
defer file_table_html.deinit();
|
||||
|
||||
for (slowest_files[0..@min(max_table_rows, slowest_files.len)]) |file| {
|
||||
try file_table_html.writer.print(
|
||||
\\<tr>
|
||||
\\ <th scope="row"><code>{f}</code></th>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\</tr>
|
||||
\\
|
||||
, .{
|
||||
fmtEscapeHtml(file.name),
|
||||
file.ns_sema,
|
||||
file.ns_codegen,
|
||||
file.ns_link,
|
||||
file.ns_sema + file.ns_codegen + file.ns_link,
|
||||
});
|
||||
}
|
||||
if (slowest_files.len > max_table_rows) {
|
||||
try file_table_html.writer.print(
|
||||
\\<tr><td colspan="4">{d} more rows omitted</td></tr>
|
||||
\\
|
||||
, .{slowest_files.len - max_table_rows});
|
||||
}
|
||||
|
||||
var decl_table_html: std.Io.Writer.Allocating = .init(gpa);
|
||||
defer decl_table_html.deinit();
|
||||
|
||||
for (slowest_decls[0..@min(max_table_rows, slowest_decls.len)]) |decl| {
|
||||
try decl_table_html.writer.print(
|
||||
\\<tr>
|
||||
\\ <th scope="row"><code>{f}</code></th>
|
||||
\\ <th scope="row"><code>{f}</code></th>
|
||||
\\ <td>{d}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\ <td>{D}</td>
|
||||
\\</tr>
|
||||
\\
|
||||
, .{
|
||||
fmtEscapeHtml(decl.file_name),
|
||||
fmtEscapeHtml(decl.name),
|
||||
decl.sema_count,
|
||||
decl.ns_sema,
|
||||
decl.ns_codegen,
|
||||
decl.ns_link,
|
||||
decl.ns_sema + decl.ns_codegen + decl.ns_link,
|
||||
});
|
||||
}
|
||||
if (slowest_decls.len > max_table_rows) {
|
||||
try decl_table_html.writer.print(
|
||||
\\<tr><td colspan="6">{d} more rows omitted</td></tr>
|
||||
\\
|
||||
, .{slowest_decls.len - max_table_rows});
|
||||
}
|
||||
|
||||
js.updateCompile(
|
||||
hdr.step_idx,
|
||||
inner_html.ptr,
|
||||
inner_html.len,
|
||||
file_table_html.written().ptr,
|
||||
file_table_html.written().len,
|
||||
decl_table_html.written().ptr,
|
||||
decl_table_html.written().len,
|
||||
hdr.flags.use_llvm,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void {
|
||||
if (msg_bytes.len < @sizeOf(abi.RunTestResult)) @panic("malformed RunTestResult message");
|
||||
const hdr: *const abi.RunTestResult = @ptrCast(msg_bytes[0..@sizeOf(abi.RunTestResult)]);
|
||||
if (hdr.step_idx >= step_list.*.len) @panic("malformed RunTestResult message");
|
||||
const trailing = msg_bytes[@sizeOf(abi.RunTestResult)..];
|
||||
|
||||
const durations: []align(1) const u64 = @ptrCast(trailing[0 .. hdr.tests_len * 8]);
|
||||
var offset: usize = hdr.tests_len * 8;
|
||||
|
||||
var table_html: std.ArrayList(u8) = .empty;
|
||||
defer table_html.deinit(gpa);
|
||||
|
||||
for (durations) |test_ns| {
|
||||
const test_name_len = std.mem.indexOfScalar(u8, trailing[offset..], 0) orelse @panic("malformed RunTestResult message");
|
||||
const test_name = trailing[offset..][0..test_name_len];
|
||||
offset += test_name_len + 1;
|
||||
try table_html.print(gpa, "<tr><th scope=\"row\"><code>{f}</code></th>", .{fmtEscapeHtml(test_name)});
|
||||
if (test_ns == std.math.maxInt(u64)) {
|
||||
try table_html.appendSlice(gpa, "<td class=\"empty-cell\"></td>"); // didn't run
|
||||
} else {
|
||||
try table_html.print(gpa, "<td>{D}</td>", .{test_ns});
|
||||
}
|
||||
try table_html.appendSlice(gpa, "</tr>\n");
|
||||
}
|
||||
|
||||
if (offset != trailing.len) @panic("malformed RunTestResult message");
|
||||
|
||||
js.updateRunTest(
|
||||
hdr.step_idx,
|
||||
table_html.items.ptr,
|
||||
table_html.items.len,
|
||||
);
|
||||
}
|
||||
198
lib/c.zig
198
lib/c.zig
@ -1,38 +1,180 @@
|
||||
//! This is Zig's multi-target implementation of libc.
|
||||
//!
|
||||
//! When `builtin.link_libc` is true, we need to export all the functions and
|
||||
//! provide a libc API compatible with the target (e.g. musl, wasi-libc, ...).
|
||||
//! When builtin.link_libc is true, we need to export all the functions and
|
||||
//! provide an entire C API.
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const math = std.math;
|
||||
const isNan = std.math.isNan;
|
||||
const maxInt = std.math.maxInt;
|
||||
const native_os = builtin.os.tag;
|
||||
const native_arch = builtin.cpu.arch;
|
||||
const native_abi = builtin.abi;
|
||||
|
||||
// Avoid dragging in the runtime safety mechanisms into this .o file, unless
|
||||
// we're trying to test zigc.
|
||||
pub const panic = if (builtin.is_test)
|
||||
std.debug.FullPanic(std.debug.defaultPanic)
|
||||
else
|
||||
std.debug.no_panic;
|
||||
const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .strong;
|
||||
|
||||
const is_wasm = switch (native_arch) {
|
||||
.wasm32, .wasm64 => true,
|
||||
else => false,
|
||||
};
|
||||
const is_freestanding = switch (native_os) {
|
||||
.freestanding, .other => true,
|
||||
else => false,
|
||||
};
|
||||
|
||||
comptime {
|
||||
_ = @import("c/inttypes.zig");
|
||||
_ = @import("c/stdlib.zig");
|
||||
_ = @import("c/math.zig");
|
||||
|
||||
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
|
||||
// Files specific to musl and wasi-libc.
|
||||
_ = @import("c/string.zig");
|
||||
_ = @import("c/strings.zig");
|
||||
if (is_freestanding and is_wasm and builtin.link_libc) {
|
||||
@export(&wasm_start, .{ .name = "_start", .linkage = .strong });
|
||||
}
|
||||
|
||||
if (builtin.target.isMuslLibC()) {
|
||||
// Files specific to musl.
|
||||
}
|
||||
|
||||
if (builtin.target.isWasiLibC()) {
|
||||
// Files specific to wasi-libc.
|
||||
}
|
||||
|
||||
if (builtin.target.isMinGW()) {
|
||||
// Files specific to MinGW-w64.
|
||||
if (builtin.link_libc) {
|
||||
@export(&strcmp, .{ .name = "strcmp", .linkage = linkage });
|
||||
@export(&strncmp, .{ .name = "strncmp", .linkage = linkage });
|
||||
@export(&strerror, .{ .name = "strerror", .linkage = linkage });
|
||||
@export(&strlen, .{ .name = "strlen", .linkage = linkage });
|
||||
@export(&strcpy, .{ .name = "strcpy", .linkage = linkage });
|
||||
@export(&strncpy, .{ .name = "strncpy", .linkage = linkage });
|
||||
@export(&strcat, .{ .name = "strcat", .linkage = linkage });
|
||||
@export(&strncat, .{ .name = "strncat", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid dragging in the runtime safety mechanisms into this .o file,
|
||||
// unless we're trying to test this file.
|
||||
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
@branchHint(.cold);
|
||||
_ = error_return_trace;
|
||||
if (builtin.is_test) {
|
||||
std.debug.panic("{s}", .{msg});
|
||||
}
|
||||
switch (native_os) {
|
||||
.freestanding, .other, .amdhsa, .amdpal => while (true) {},
|
||||
else => std.os.abort(),
|
||||
}
|
||||
}
|
||||
|
||||
extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
|
||||
fn wasm_start() callconv(.C) void {
|
||||
_ = main(0, undefined);
|
||||
}
|
||||
|
||||
fn strcpy(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 {
|
||||
var i: usize = 0;
|
||||
while (src[i] != 0) : (i += 1) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
dest[i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
test "strcpy" {
|
||||
var s1: [9:0]u8 = undefined;
|
||||
|
||||
s1[0] = 0;
|
||||
_ = strcpy(&s1, "foobarbaz");
|
||||
try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
|
||||
}
|
||||
|
||||
fn strncpy(dest: [*:0]u8, src: [*:0]const u8, n: usize) callconv(.C) [*:0]u8 {
|
||||
var i: usize = 0;
|
||||
while (i < n and src[i] != 0) : (i += 1) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
while (i < n) : (i += 1) {
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
test "strncpy" {
|
||||
var s1: [9:0]u8 = undefined;
|
||||
|
||||
s1[0] = 0;
|
||||
_ = strncpy(&s1, "foobarbaz", @sizeOf(@TypeOf(s1)));
|
||||
try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
|
||||
}
|
||||
|
||||
fn strcat(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 {
|
||||
var dest_end: usize = 0;
|
||||
while (dest[dest_end] != 0) : (dest_end += 1) {}
|
||||
|
||||
var i: usize = 0;
|
||||
while (src[i] != 0) : (i += 1) {
|
||||
dest[dest_end + i] = src[i];
|
||||
}
|
||||
dest[dest_end + i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
test "strcat" {
|
||||
var s1: [9:0]u8 = undefined;
|
||||
|
||||
s1[0] = 0;
|
||||
_ = strcat(&s1, "foo");
|
||||
_ = strcat(&s1, "bar");
|
||||
_ = strcat(&s1, "baz");
|
||||
try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
|
||||
}
|
||||
|
||||
fn strncat(dest: [*:0]u8, src: [*:0]const u8, avail: usize) callconv(.C) [*:0]u8 {
|
||||
var dest_end: usize = 0;
|
||||
while (dest[dest_end] != 0) : (dest_end += 1) {}
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < avail and src[i] != 0) : (i += 1) {
|
||||
dest[dest_end + i] = src[i];
|
||||
}
|
||||
dest[dest_end + i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
test "strncat" {
|
||||
var s1: [9:0]u8 = undefined;
|
||||
|
||||
s1[0] = 0;
|
||||
_ = strncat(&s1, "foo1111", 3);
|
||||
_ = strncat(&s1, "bar1111", 3);
|
||||
_ = strncat(&s1, "baz1111", 3);
|
||||
try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
|
||||
}
|
||||
|
||||
fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int {
|
||||
return switch (std.mem.orderZ(u8, s1, s2)) {
|
||||
.lt => -1,
|
||||
.eq => 0,
|
||||
.gt => 1,
|
||||
};
|
||||
}
|
||||
|
||||
fn strlen(s: [*:0]const u8) callconv(.C) usize {
|
||||
return std.mem.len(s);
|
||||
}
|
||||
|
||||
fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) callconv(.C) c_int {
|
||||
if (_n == 0) return 0;
|
||||
var l = _l;
|
||||
var r = _r;
|
||||
var n = _n - 1;
|
||||
while (l[0] != 0 and r[0] != 0 and n != 0 and l[0] == r[0]) {
|
||||
l += 1;
|
||||
r += 1;
|
||||
n -= 1;
|
||||
}
|
||||
return @as(c_int, l[0]) - @as(c_int, r[0]);
|
||||
}
|
||||
|
||||
fn strerror(errnum: c_int) callconv(.C) [*:0]const u8 {
|
||||
_ = errnum;
|
||||
return "TODO strerror implementation";
|
||||
}
|
||||
|
||||
test "strncmp" {
|
||||
try std.testing.expect(strncmp("a", "b", 1) < 0);
|
||||
try std.testing.expect(strncmp("a", "c", 1) < 0);
|
||||
try std.testing.expect(strncmp("b", "a", 1) > 0);
|
||||
try std.testing.expect(strncmp("\xff", "\x02", 1) > 0);
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
|
||||
pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test)
|
||||
.internal
|
||||
else
|
||||
.strong;
|
||||
|
||||
/// Determines the symbol's visibility to other objects.
|
||||
/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
|
||||
/// export it to the host runtime.
|
||||
pub const visibility: std.builtin.SymbolVisibility = if (linkage != .internal)
|
||||
.hidden
|
||||
else
|
||||
.default;
|
||||
@ -1,20 +0,0 @@
|
||||
const std = @import("std");
|
||||
const common = @import("common.zig");
|
||||
const builtin = @import("builtin");
|
||||
const intmax_t = std.c.intmax_t;
|
||||
|
||||
comptime {
|
||||
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
|
||||
// Functions specific to musl and wasi-libc.
|
||||
@export(&imaxabs, .{ .name = "imaxabs", .linkage = common.linkage, .visibility = common.visibility });
|
||||
}
|
||||
}
|
||||
|
||||
fn imaxabs(a: intmax_t) callconv(.c) intmax_t {
|
||||
return @intCast(@abs(a));
|
||||
}
|
||||
|
||||
test imaxabs {
|
||||
const val: intmax_t = -10;
|
||||
try std.testing.expectEqual(10, imaxabs(val));
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
const std = @import("std");
|
||||
const common = @import("common.zig");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
comptime {
|
||||
if (builtin.target.isMinGW()) {
|
||||
@export(&isnan, .{ .name = "isnan", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&isnan, .{ .name = "__isnan", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&isnanf, .{ .name = "isnanf", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&isnanf, .{ .name = "__isnanf", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&isnanl, .{ .name = "isnanl", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&isnanl, .{ .name = "__isnanl", .linkage = common.linkage, .visibility = common.visibility });
|
||||
}
|
||||
}
|
||||
|
||||
fn isnan(x: f64) callconv(.c) c_int {
|
||||
return if (std.math.isNan(x)) 1 else 0;
|
||||
}
|
||||
|
||||
fn isnanf(x: f32) callconv(.c) c_int {
|
||||
return if (std.math.isNan(x)) 1 else 0;
|
||||
}
|
||||
|
||||
fn isnanl(x: c_longdouble) callconv(.c) c_int {
|
||||
return if (std.math.isNan(x)) 1 else 0;
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
const std = @import("std");
|
||||
const common = @import("common.zig");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
comptime {
|
||||
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
|
||||
// Functions specific to musl and wasi-libc.
|
||||
@export(&abs, .{ .name = "abs", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&labs, .{ .name = "labs", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&llabs, .{ .name = "llabs", .linkage = common.linkage, .visibility = common.visibility });
|
||||
}
|
||||
}
|
||||
|
||||
fn abs(a: c_int) callconv(.c) c_int {
|
||||
return @intCast(@abs(a));
|
||||
}
|
||||
|
||||
fn labs(a: c_long) callconv(.c) c_long {
|
||||
return @intCast(@abs(a));
|
||||
}
|
||||
|
||||
fn llabs(a: c_longlong) callconv(.c) c_longlong {
|
||||
return @intCast(@abs(a));
|
||||
}
|
||||
|
||||
test abs {
|
||||
const val: c_int = -10;
|
||||
try std.testing.expectEqual(10, abs(val));
|
||||
}
|
||||
|
||||
test labs {
|
||||
const val: c_long = -10;
|
||||
try std.testing.expectEqual(10, labs(val));
|
||||
}
|
||||
|
||||
test llabs {
|
||||
const val: c_longlong = -10;
|
||||
try std.testing.expectEqual(10, llabs(val));
|
||||
}
|
||||
104
lib/c/string.zig
104
lib/c/string.zig
@ -1,104 +0,0 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const common = @import("common.zig");
|
||||
|
||||
comptime {
|
||||
@export(&strcmp, .{ .name = "strcmp", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&strncmp, .{ .name = "strncmp", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&strcasecmp, .{ .name = "strcasecmp", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&strncasecmp, .{ .name = "strncasecmp", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__strcasecmp_l, .{ .name = "__strcasecmp_l", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__strncasecmp_l, .{ .name = "__strncasecmp_l", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__strcasecmp_l, .{ .name = "strcasecmp_l", .linkage = .weak, .visibility = common.visibility });
|
||||
@export(&__strncasecmp_l, .{ .name = "strncasecmp_l", .linkage = .weak, .visibility = common.visibility });
|
||||
}
|
||||
|
||||
fn strcmp(s1: [*:0]const c_char, s2: [*:0]const c_char) callconv(.c) c_int {
|
||||
// We need to perform unsigned comparisons.
|
||||
return switch (std.mem.orderZ(u8, @ptrCast(s1), @ptrCast(s2))) {
|
||||
.lt => -1,
|
||||
.eq => 0,
|
||||
.gt => 1,
|
||||
};
|
||||
}
|
||||
|
||||
fn strncmp(s1: [*:0]const c_char, s2: [*:0]const c_char, n: usize) callconv(.c) c_int {
|
||||
if (n == 0) return 0;
|
||||
|
||||
var l: [*:0]const u8 = @ptrCast(s1);
|
||||
var r: [*:0]const u8 = @ptrCast(s2);
|
||||
var i = n - 1;
|
||||
|
||||
while (l[0] != 0 and r[0] != 0 and i != 0 and l[0] == r[0]) {
|
||||
l += 1;
|
||||
r += 1;
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
return @as(c_int, l[0]) - @as(c_int, r[0]);
|
||||
}
|
||||
|
||||
fn strcasecmp(s1: [*:0]const c_char, s2: [*:0]const c_char) callconv(.c) c_int {
|
||||
const toLower = std.ascii.toLower;
|
||||
var l: [*:0]const u8 = @ptrCast(s1);
|
||||
var r: [*:0]const u8 = @ptrCast(s2);
|
||||
|
||||
while (l[0] != 0 and r[0] != 0 and (l[0] == r[0] or toLower(l[0]) == toLower(r[0]))) {
|
||||
l += 1;
|
||||
r += 1;
|
||||
}
|
||||
|
||||
return @as(c_int, toLower(l[0])) - @as(c_int, toLower(r[0]));
|
||||
}
|
||||
|
||||
fn __strcasecmp_l(s1: [*:0]const c_char, s2: [*:0]const c_char, locale: *anyopaque) callconv(.c) c_int {
|
||||
_ = locale;
|
||||
return strcasecmp(s1, s2);
|
||||
}
|
||||
|
||||
fn strncasecmp(s1: [*:0]const c_char, s2: [*:0]const c_char, n: usize) callconv(.c) c_int {
|
||||
const toLower = std.ascii.toLower;
|
||||
var l: [*:0]const u8 = @ptrCast(s1);
|
||||
var r: [*:0]const u8 = @ptrCast(s2);
|
||||
var i = n - 1;
|
||||
|
||||
while (l[0] != 0 and r[0] != 0 and i != 0 and (l[0] == r[0] or toLower(l[0]) == toLower(r[0]))) {
|
||||
l += 1;
|
||||
r += 1;
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
return @as(c_int, toLower(l[0])) - @as(c_int, toLower(r[0]));
|
||||
}
|
||||
|
||||
fn __strncasecmp_l(s1: [*:0]const c_char, s2: [*:0]const c_char, n: usize, locale: *anyopaque) callconv(.c) c_int {
|
||||
_ = locale;
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
||||
test strcasecmp {
|
||||
try std.testing.expect(strcasecmp(@ptrCast("a"), @ptrCast("b")) < 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("a")) > 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("b")) < 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("A")) > 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("A")) == 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("B"), @ptrCast("b")) == 0);
|
||||
try std.testing.expect(strcasecmp(@ptrCast("bb"), @ptrCast("AA")) > 0);
|
||||
}
|
||||
|
||||
test strncasecmp {
|
||||
try std.testing.expect(strncasecmp(@ptrCast("a"), @ptrCast("b"), 1) < 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("a"), 1) > 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("b"), 1) < 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("A"), 1) > 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("A"), 1) == 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("B"), @ptrCast("b"), 1) == 0);
|
||||
try std.testing.expect(strncasecmp(@ptrCast("bb"), @ptrCast("AA"), 2) > 0);
|
||||
}
|
||||
|
||||
test strncmp {
|
||||
try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("b"), 1) < 0);
|
||||
try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("c"), 1) < 0);
|
||||
try std.testing.expect(strncmp(@ptrCast("b"), @ptrCast("a"), 1) > 0);
|
||||
try std.testing.expect(strncmp(@ptrCast("\xff"), @ptrCast("\x02"), 1) > 0);
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
const std = @import("std");
|
||||
const common = @import("common.zig");
|
||||
|
||||
comptime {
|
||||
@export(&bzero, .{ .name = "bzero", .linkage = common.linkage, .visibility = common.visibility });
|
||||
}
|
||||
|
||||
fn bzero(s: *anyopaque, n: usize) callconv(.c) void {
|
||||
const s_cast: [*]u8 = @ptrCast(s);
|
||||
@memset(s_cast[0..n], 0);
|
||||
}
|
||||
|
||||
test bzero {
|
||||
var array: [10]u8 = [_]u8{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
|
||||
var a = std.mem.zeroes([array.len]u8);
|
||||
a[9] = '0';
|
||||
bzero(&array[0], 9);
|
||||
try std.testing.expect(std.mem.eql(u8, &array, &a));
|
||||
}
|
||||
26
lib/compiler/aro/README.md
vendored
Normal file
26
lib/compiler/aro/README.md
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<img src="https://aro.vexu.eu/aro-logo.svg" alt="Aro" width="120px"/>
|
||||
|
||||
# Aro
|
||||
|
||||
A C compiler with the goal of providing fast compilation and low memory usage with good diagnostics.
|
||||
|
||||
Aro is included as an alternative C frontend in the [Zig compiler](https://github.com/ziglang/zig)
|
||||
for `translate-c` and eventually compiling C files by translating them to Zig first.
|
||||
Aro is developed in https://github.com/Vexu/arocc and the Zig dependency is
|
||||
updated from there when needed.
|
||||
|
||||
Currently most of standard C is supported up to C23 and as are many of the common
|
||||
extensions from GNU, MSVC, and Clang
|
||||
|
||||
Basic code generation is supported for x86-64 linux and can produce a valid hello world:
|
||||
```sh-session
|
||||
$ cat hello.c
|
||||
extern int printf(const char *restrict fmt, ...);
|
||||
int main(void) {
|
||||
printf("Hello, world!\n");
|
||||
return 0;
|
||||
}
|
||||
$ zig build && ./zig-out/bin/arocc hello.c -o hello
|
||||
$ ./hello
|
||||
Hello, world!
|
||||
```
|
||||
14
lib/compiler/aro/aro.zig
vendored
14
lib/compiler/aro/aro.zig
vendored
@ -5,14 +5,12 @@ pub const Driver = @import("aro/Driver.zig");
|
||||
pub const Parser = @import("aro/Parser.zig");
|
||||
pub const Preprocessor = @import("aro/Preprocessor.zig");
|
||||
pub const Source = @import("aro/Source.zig");
|
||||
pub const StringInterner = @import("aro/StringInterner.zig");
|
||||
pub const Target = @import("aro/Target.zig");
|
||||
pub const Tokenizer = @import("aro/Tokenizer.zig");
|
||||
pub const Toolchain = @import("aro/Toolchain.zig");
|
||||
pub const Tree = @import("aro/Tree.zig");
|
||||
pub const TypeStore = @import("aro/TypeStore.zig");
|
||||
pub const QualType = TypeStore.QualType;
|
||||
pub const Type = TypeStore.Type;
|
||||
pub const Type = @import("aro/Type.zig");
|
||||
pub const TypeMapper = @import("aro/StringInterner.zig").TypeMapper;
|
||||
pub const target_util = @import("aro/target.zig");
|
||||
pub const Value = @import("aro/Value.zig");
|
||||
|
||||
const backend = @import("backend.zig");
|
||||
@ -20,7 +18,6 @@ pub const Interner = backend.Interner;
|
||||
pub const Ir = backend.Ir;
|
||||
pub const Object = backend.Object;
|
||||
pub const CallingConvention = backend.CallingConvention;
|
||||
pub const Assembly = backend.Assembly;
|
||||
|
||||
pub const version_str = backend.version_str;
|
||||
pub const version = backend.version;
|
||||
@ -31,11 +28,12 @@ test {
|
||||
_ = @import("aro/char_info.zig");
|
||||
_ = @import("aro/Compilation.zig");
|
||||
_ = @import("aro/Driver/Distro.zig");
|
||||
_ = @import("aro/Driver/Filesystem.zig");
|
||||
_ = @import("aro/Driver/GCCVersion.zig");
|
||||
_ = @import("aro/InitList.zig");
|
||||
_ = @import("aro/LangOpts.zig");
|
||||
_ = @import("aro/Preprocessor.zig");
|
||||
_ = @import("aro/Target.zig");
|
||||
_ = @import("aro/target.zig");
|
||||
_ = @import("aro/Tokenizer.zig");
|
||||
_ = @import("aro/toolchains/Linux.zig");
|
||||
_ = @import("aro/Value.zig");
|
||||
}
|
||||
|
||||
833
lib/compiler/aro/aro/Attribute.zig
vendored
833
lib/compiler/aro/aro/Attribute.zig
vendored
File diff suppressed because it is too large
Load Diff
1742
lib/compiler/aro/aro/Attribute/names.zig
vendored
1742
lib/compiler/aro/aro/Attribute/names.zig
vendored
File diff suppressed because it is too large
Load Diff
521
lib/compiler/aro/aro/Builtins.zig
vendored
521
lib/compiler/aro/aro/Builtins.zig
vendored
@ -1,115 +1,62 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Compilation = @import("Compilation.zig");
|
||||
const Type = @import("Type.zig");
|
||||
const TypeDescription = @import("Builtins/TypeDescription.zig");
|
||||
const target_util = @import("target.zig");
|
||||
const StringId = @import("StringInterner.zig").StringId;
|
||||
const LangOpts = @import("LangOpts.zig");
|
||||
const Parser = @import("Parser.zig");
|
||||
const Target = @import("Target.zig");
|
||||
const TypeStore = @import("TypeStore.zig");
|
||||
const QualType = TypeStore.QualType;
|
||||
const Builder = TypeStore.Builder;
|
||||
const TypeDescription = @import("Builtins/TypeDescription.zig");
|
||||
const properties = @import("Builtins/properties.zig");
|
||||
|
||||
const BuiltinBase = struct {
|
||||
param_str: [*:0]const u8,
|
||||
language: properties.Language = .all_languages,
|
||||
attributes: properties.Attributes = .{},
|
||||
header: properties.Header = .none,
|
||||
const Properties = @import("Builtins/Properties.zig");
|
||||
pub const Builtin = @import("Builtins/Builtin.zig").with(Properties);
|
||||
|
||||
const Expanded = struct {
|
||||
ty: Type,
|
||||
builtin: Builtin,
|
||||
};
|
||||
|
||||
const BuiltinTarget = struct {
|
||||
param_str: [*:0]const u8,
|
||||
language: properties.Language = .all_languages,
|
||||
attributes: properties.Attributes = .{},
|
||||
header: properties.Header = .none,
|
||||
features: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
const aarch64 = @import("Builtins/aarch64.zig").with(BuiltinTarget);
|
||||
const amdgcn = @import("Builtins/amdgcn.zig").with(BuiltinTarget);
|
||||
const arm = @import("Builtins/arm.zig").with(BuiltinTarget);
|
||||
const bpf = @import("Builtins/bpf.zig").with(BuiltinTarget);
|
||||
const common = @import("Builtins/common.zig").with(BuiltinBase);
|
||||
const hexagon = @import("Builtins/hexagon.zig").with(BuiltinTarget);
|
||||
const loongarch = @import("Builtins/loongarch.zig").with(BuiltinTarget);
|
||||
const mips = @import("Builtins/mips.zig").with(BuiltinBase);
|
||||
const nvptx = @import("Builtins/nvptx.zig").with(BuiltinTarget);
|
||||
const powerpc = @import("Builtins/powerpc.zig").with(BuiltinTarget);
|
||||
const riscv = @import("Builtins/riscv.zig").with(BuiltinTarget);
|
||||
const s390x = @import("Builtins/s390x.zig").with(BuiltinTarget);
|
||||
const ve = @import("Builtins/ve.zig").with(BuiltinBase);
|
||||
const x86_64 = @import("Builtins/x86_64.zig").with(BuiltinTarget);
|
||||
const x86 = @import("Builtins/x86.zig").with(BuiltinTarget);
|
||||
const xcore = @import("Builtins/xcore.zig").with(BuiltinBase);
|
||||
|
||||
pub const Tag = union(enum) {
|
||||
aarch64: aarch64.Tag,
|
||||
amdgcn: amdgcn.Tag,
|
||||
arm: arm.Tag,
|
||||
bpf: bpf.Tag,
|
||||
common: common.Tag,
|
||||
hexagon: hexagon.Tag,
|
||||
loongarch: loongarch.Tag,
|
||||
mips: mips.Tag,
|
||||
nvptx: nvptx.Tag,
|
||||
powerpc: powerpc.Tag,
|
||||
riscv: riscv.Tag,
|
||||
s390x: s390x.Tag,
|
||||
ve: ve.Tag,
|
||||
x86_64: x86_64.Tag,
|
||||
x86: x86.Tag,
|
||||
xcore: xcore.Tag,
|
||||
};
|
||||
|
||||
pub const Expanded = struct {
|
||||
tag: Tag,
|
||||
qt: QualType,
|
||||
language: properties.Language = .all_languages,
|
||||
attributes: properties.Attributes = .{},
|
||||
header: properties.Header = .none,
|
||||
};
|
||||
const NameToTypeMap = std.StringHashMapUnmanaged(Type);
|
||||
|
||||
const Builtins = @This();
|
||||
|
||||
_name_to_type_map: std.StringHashMapUnmanaged(Expanded) = .{},
|
||||
_name_to_type_map: NameToTypeMap = .{},
|
||||
|
||||
pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void {
|
||||
b._name_to_type_map.deinit(gpa);
|
||||
}
|
||||
|
||||
fn specForSize(comp: *const Compilation, size_bits: u32) TypeStore.Builder.Specifier {
|
||||
var qt: QualType = .short;
|
||||
if (qt.bitSizeof(comp) == size_bits) return .short;
|
||||
fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier {
|
||||
var ty = Type{ .specifier = .short };
|
||||
if (ty.sizeof(comp).? * 8 == size_bits) return .short;
|
||||
|
||||
qt = .int;
|
||||
if (qt.bitSizeof(comp) == size_bits) return .int;
|
||||
ty.specifier = .int;
|
||||
if (ty.sizeof(comp).? * 8 == size_bits) return .int;
|
||||
|
||||
qt = .long;
|
||||
if (qt.bitSizeof(comp) == size_bits) return .long;
|
||||
ty.specifier = .long;
|
||||
if (ty.sizeof(comp).? * 8 == size_bits) return .long;
|
||||
|
||||
qt = .long_long;
|
||||
if (qt.bitSizeof(comp) == size_bits) return .long_long;
|
||||
ty.specifier = .long_long;
|
||||
if (ty.sizeof(comp).? * 8 == size_bits) return .long_long;
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *Compilation) !QualType {
|
||||
var parser: Parser = undefined;
|
||||
parser.comp = comp;
|
||||
var builder: TypeStore.Builder = .{ .parser = &parser, .error_on_invalid = true };
|
||||
var actual_suffix = desc.suffix;
|
||||
|
||||
fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type {
|
||||
var builder: Type.Builder = .{ .error_on_invalid = true };
|
||||
var require_native_int32 = false;
|
||||
var require_native_int64 = false;
|
||||
for (desc.prefix) |prefix| {
|
||||
switch (prefix) {
|
||||
.L => builder.combine(.long, 0) catch unreachable,
|
||||
.LL => builder.combine(.long_long, 0) catch unreachable,
|
||||
.L => builder.combine(undefined, .long, 0) catch unreachable,
|
||||
.LL => {
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
},
|
||||
.LLL => {
|
||||
switch (builder.type) {
|
||||
.none => builder.type = .int128,
|
||||
.signed => builder.type = .sint128,
|
||||
.unsigned => builder.type = .uint128,
|
||||
switch (builder.specifier) {
|
||||
.none => builder.specifier = .int128,
|
||||
.signed => builder.specifier = .sint128,
|
||||
.unsigned => builder.specifier = .uint128,
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
@ -117,285 +64,331 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *C
|
||||
.W => require_native_int64 = true,
|
||||
.N => {
|
||||
std.debug.assert(desc.spec == .i);
|
||||
if (!comp.target.isLP64()) {
|
||||
builder.combine(.long, 0) catch unreachable;
|
||||
if (!target_util.isLP64(comp.target)) {
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
}
|
||||
},
|
||||
.O => {
|
||||
builder.combine(.long, 0) catch unreachable;
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
if (comp.target.os.tag != .opencl) {
|
||||
builder.combine(.long, 0) catch unreachable;
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
}
|
||||
},
|
||||
.S => builder.combine(.signed, 0) catch unreachable,
|
||||
.U => builder.combine(.unsigned, 0) catch unreachable,
|
||||
.S => builder.combine(undefined, .signed, 0) catch unreachable,
|
||||
.U => builder.combine(undefined, .unsigned, 0) catch unreachable,
|
||||
.I => {
|
||||
// Todo: compile-time constant integer
|
||||
},
|
||||
}
|
||||
}
|
||||
switch (desc.spec) {
|
||||
.v => builder.combine(.void, 0) catch unreachable,
|
||||
.b => builder.combine(.bool, 0) catch unreachable,
|
||||
.c => builder.combine(.char, 0) catch unreachable,
|
||||
.s => builder.combine(.short, 0) catch unreachable,
|
||||
.v => builder.combine(undefined, .void, 0) catch unreachable,
|
||||
.b => builder.combine(undefined, .bool, 0) catch unreachable,
|
||||
.c => builder.combine(undefined, .char, 0) catch unreachable,
|
||||
.s => builder.combine(undefined, .short, 0) catch unreachable,
|
||||
.i => {
|
||||
if (require_native_int32) {
|
||||
builder.type = specForSize(comp, 32);
|
||||
builder.specifier = specForSize(comp, 32);
|
||||
} else if (require_native_int64) {
|
||||
builder.type = specForSize(comp, 64);
|
||||
builder.specifier = specForSize(comp, 64);
|
||||
} else {
|
||||
switch (builder.type) {
|
||||
switch (builder.specifier) {
|
||||
.int128, .sint128, .uint128 => {},
|
||||
else => builder.combine(.int, 0) catch unreachable,
|
||||
else => builder.combine(undefined, .int, 0) catch unreachable,
|
||||
}
|
||||
}
|
||||
},
|
||||
.h => builder.combine(.fp16, 0) catch unreachable,
|
||||
.x => builder.combine(.float16, 0) catch unreachable,
|
||||
.y => builder.combine(.bf16, 0) catch unreachable,
|
||||
.f => builder.combine(.float, 0) catch unreachable,
|
||||
.h => builder.combine(undefined, .fp16, 0) catch unreachable,
|
||||
.x => builder.combine(undefined, .float16, 0) catch unreachable,
|
||||
.y => {
|
||||
// Todo: __bf16
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.f => builder.combine(undefined, .float, 0) catch unreachable,
|
||||
.d => {
|
||||
if (builder.type == .long_long) {
|
||||
builder.type = .float128;
|
||||
if (builder.specifier == .long_long) {
|
||||
builder.specifier = .float128;
|
||||
} else {
|
||||
builder.combine(.double, 0) catch unreachable;
|
||||
builder.combine(undefined, .double, 0) catch unreachable;
|
||||
}
|
||||
},
|
||||
.z => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.size);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.size);
|
||||
},
|
||||
.w => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.wchar);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.wchar);
|
||||
},
|
||||
.F => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.ns_constant_string);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty);
|
||||
},
|
||||
.G => {
|
||||
// Todo: id
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.H => {
|
||||
// Todo: SEL
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.M => {
|
||||
// Todo: struct objc_super
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.a => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.va_list);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.va_list);
|
||||
},
|
||||
.A => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
var va_list = comp.type_store.va_list;
|
||||
std.debug.assert(!va_list.is(comp, .array));
|
||||
builder.type = Builder.fromType(comp, va_list);
|
||||
var va_list = comp.types.va_list;
|
||||
if (va_list.isArray()) va_list.decayArray();
|
||||
builder.specifier = Type.Builder.fromType(va_list);
|
||||
},
|
||||
.V => |element_count| {
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
var child_desc = it.next().?;
|
||||
actual_suffix = child_desc.suffix;
|
||||
child_desc.suffix = &.{};
|
||||
const elem_qt = try createType(child_desc, undefined, comp);
|
||||
const vector_qt = try comp.type_store.put(comp.gpa, .{ .vector = .{
|
||||
.elem = elem_qt,
|
||||
const child_desc = it.next().?;
|
||||
const child_ty = try createType(child_desc, undefined, comp, allocator);
|
||||
const arr_ty = try allocator.create(Type.Array);
|
||||
arr_ty.* = .{
|
||||
.len = element_count,
|
||||
} });
|
||||
builder.type = .{ .other = vector_qt };
|
||||
.elem = child_ty,
|
||||
};
|
||||
const vector_ty: Type = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
|
||||
builder.specifier = Type.Builder.fromType(vector_ty);
|
||||
},
|
||||
.Q => {
|
||||
// Todo: target builtin type
|
||||
return .invalid;
|
||||
.q => {
|
||||
// Todo: scalable vector
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.E => {
|
||||
// Todo: ext_vector (OpenCL vector)
|
||||
return .invalid;
|
||||
return .{ .specifier = .invalid };
|
||||
},
|
||||
.X => |child| {
|
||||
builder.combine(.complex, 0) catch unreachable;
|
||||
builder.combine(undefined, .complex, 0) catch unreachable;
|
||||
switch (child) {
|
||||
.float => builder.combine(.float, 0) catch unreachable,
|
||||
.double => builder.combine(.double, 0) catch unreachable,
|
||||
.float => builder.combine(undefined, .float, 0) catch unreachable,
|
||||
.double => builder.combine(undefined, .double, 0) catch unreachable,
|
||||
.longdouble => {
|
||||
builder.combine(.long, 0) catch unreachable;
|
||||
builder.combine(.double, 0) catch unreachable;
|
||||
builder.combine(undefined, .long, 0) catch unreachable;
|
||||
builder.combine(undefined, .double, 0) catch unreachable;
|
||||
},
|
||||
}
|
||||
},
|
||||
.Y => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.ptrdiff);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.ptrdiff);
|
||||
},
|
||||
.P => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
if (comp.type_store.file.isInvalid()) {
|
||||
return comp.type_store.file;
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
if (comp.types.file.specifier == .invalid) {
|
||||
return comp.types.file;
|
||||
}
|
||||
builder.type = Builder.fromType(comp, comp.type_store.file);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.file);
|
||||
},
|
||||
.J => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
if (comp.type_store.jmp_buf.isInvalid()) {
|
||||
return comp.type_store.jmp_buf;
|
||||
if (comp.types.jmp_buf.specifier == .invalid) {
|
||||
return comp.types.jmp_buf;
|
||||
}
|
||||
builder.type = Builder.fromType(comp, comp.type_store.jmp_buf);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.jmp_buf);
|
||||
},
|
||||
.SJ => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
if (comp.type_store.sigjmp_buf.isInvalid()) {
|
||||
return comp.type_store.sigjmp_buf;
|
||||
if (comp.types.sigjmp_buf.specifier == .invalid) {
|
||||
return comp.types.sigjmp_buf;
|
||||
}
|
||||
builder.type = Builder.fromType(comp, comp.type_store.sigjmp_buf);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf);
|
||||
},
|
||||
.K => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
if (comp.type_store.ucontext_t.isInvalid()) {
|
||||
return comp.type_store.ucontext_t;
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
if (comp.types.ucontext_t.specifier == .invalid) {
|
||||
return comp.types.ucontext_t;
|
||||
}
|
||||
builder.type = Builder.fromType(comp, comp.type_store.ucontext_t);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.ucontext_t);
|
||||
},
|
||||
.p => {
|
||||
std.debug.assert(builder.type == .none);
|
||||
std.debug.assert(builder.specifier == .none);
|
||||
std.debug.assert(desc.suffix.len == 0);
|
||||
builder.type = Builder.fromType(comp, comp.type_store.pid_t);
|
||||
builder.specifier = Type.Builder.fromType(comp.types.pid_t);
|
||||
},
|
||||
.@"!" => return .{ .specifier = .invalid },
|
||||
}
|
||||
for (actual_suffix) |suffix| {
|
||||
for (desc.suffix) |suffix| {
|
||||
switch (suffix) {
|
||||
.@"*" => |address_space| {
|
||||
_ = address_space; // TODO: handle address space
|
||||
const pointer_qt = try comp.type_store.put(comp.gpa, .{ .pointer = .{
|
||||
.child = builder.finish() catch unreachable,
|
||||
.decayed = null,
|
||||
} });
|
||||
|
||||
builder.@"const" = null;
|
||||
builder.@"volatile" = null;
|
||||
builder.restrict = null;
|
||||
builder.type = .{ .other = pointer_qt };
|
||||
const elem_ty = try allocator.create(Type);
|
||||
elem_ty.* = builder.finish(undefined) catch unreachable;
|
||||
const ty = Type{
|
||||
.specifier = .pointer,
|
||||
.data = .{ .sub_type = elem_ty },
|
||||
};
|
||||
builder.qual = .{};
|
||||
builder.specifier = Type.Builder.fromType(ty);
|
||||
},
|
||||
.C => builder.@"const" = 0,
|
||||
.D => builder.@"volatile" = 0,
|
||||
.R => builder.restrict = 0,
|
||||
.C => builder.qual.@"const" = 0,
|
||||
.D => builder.qual.@"volatile" = 0,
|
||||
.R => builder.qual.restrict = 0,
|
||||
}
|
||||
}
|
||||
return builder.finish() catch unreachable;
|
||||
return builder.finish(undefined) catch unreachable;
|
||||
}
|
||||
|
||||
fn createBuiltin(comp: *Compilation, param_str: [*:0]const u8) !QualType {
|
||||
var it = TypeDescription.TypeIterator.init(param_str);
|
||||
fn createBuiltin(comp: *const Compilation, builtin: Builtin, type_arena: std.mem.Allocator) !Type {
|
||||
var it = TypeDescription.TypeIterator.init(builtin.properties.param_str);
|
||||
|
||||
const ret_ty_desc = it.next().?;
|
||||
const ret_ty = try createType(ret_ty_desc, &it, comp);
|
||||
if (ret_ty_desc.spec == .@"!") {
|
||||
// Todo: handle target-dependent definition
|
||||
}
|
||||
const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena);
|
||||
var param_count: usize = 0;
|
||||
var params: [32]TypeStore.Type.Func.Param = undefined;
|
||||
var params: [Builtin.max_param_count]Type.Func.Param = undefined;
|
||||
while (it.next()) |desc| : (param_count += 1) {
|
||||
params[param_count] = .{ .name_tok = 0, .qt = try createType(desc, &it, comp), .name = .empty, .node = .null };
|
||||
params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty };
|
||||
}
|
||||
|
||||
return comp.type_store.put(comp.gpa, .{ .func = .{
|
||||
const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]);
|
||||
const func = try type_arena.create(Type.Func);
|
||||
|
||||
func.* = .{
|
||||
.return_type = ret_ty,
|
||||
.kind = if (properties.isVarArgs(param_str)) .variadic else .normal,
|
||||
.params = params[0..param_count],
|
||||
} });
|
||||
.params = duped_params,
|
||||
};
|
||||
return .{
|
||||
.specifier = if (builtin.properties.isVarArgs()) .var_args_func else .func,
|
||||
.data = .{ .func = func },
|
||||
};
|
||||
}
|
||||
|
||||
/// Asserts that the builtin has already been created
|
||||
pub fn lookup(b: *const Builtins, name: []const u8) Expanded {
|
||||
return b._name_to_type_map.get(name).?;
|
||||
}
|
||||
|
||||
pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8) !?Expanded {
|
||||
if (b._name_to_type_map.get(name)) |expanded| return expanded;
|
||||
|
||||
const builtin = fromName(comp, name) orelse return null;
|
||||
if (builtin.features) |_| {
|
||||
// TODO check features
|
||||
}
|
||||
|
||||
try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
|
||||
const expanded: Expanded = .{
|
||||
.tag = builtin.tag,
|
||||
.qt = try createBuiltin(comp, builtin.param_str),
|
||||
.attributes = builtin.attributes,
|
||||
.header = builtin.header,
|
||||
.language = builtin.language,
|
||||
const builtin = Builtin.fromName(name).?;
|
||||
const ty = b._name_to_type_map.get(name).?;
|
||||
return .{
|
||||
.builtin = builtin,
|
||||
.ty = ty,
|
||||
};
|
||||
b._name_to_type_map.putAssumeCapacity(name, expanded);
|
||||
return expanded;
|
||||
}
|
||||
|
||||
pub const FromName = struct {
|
||||
tag: Tag,
|
||||
param_str: [*:0]const u8,
|
||||
language: properties.Language = .all_languages,
|
||||
attributes: properties.Attributes = .{},
|
||||
header: properties.Header = .none,
|
||||
features: ?[*:0]const u8 = null,
|
||||
pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded {
|
||||
const ty = b._name_to_type_map.get(name) orelse {
|
||||
const builtin = Builtin.fromName(name) orelse return null;
|
||||
if (!comp.hasBuiltinFunction(builtin)) return null;
|
||||
|
||||
try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
|
||||
const ty = try createBuiltin(comp, builtin, type_arena);
|
||||
b._name_to_type_map.putAssumeCapacity(name, ty);
|
||||
|
||||
return .{
|
||||
.builtin = builtin,
|
||||
.ty = ty,
|
||||
};
|
||||
};
|
||||
const builtin = Builtin.fromName(name).?;
|
||||
return .{
|
||||
.builtin = builtin,
|
||||
.ty = ty,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Iterator = struct {
|
||||
index: u16 = 1,
|
||||
name_buf: [Builtin.longest_name]u8 = undefined,
|
||||
|
||||
pub const Entry = struct {
|
||||
/// Memory of this slice is overwritten on every call to `next`
|
||||
name: []const u8,
|
||||
builtin: Builtin,
|
||||
};
|
||||
|
||||
pub fn next(self: *Iterator) ?Entry {
|
||||
if (self.index > Builtin.data.len) return null;
|
||||
const index = self.index;
|
||||
const data_index = index - 1;
|
||||
self.index += 1;
|
||||
return .{
|
||||
.name = Builtin.nameFromUniqueIndex(index, &self.name_buf),
|
||||
.builtin = Builtin.data[data_index],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn fromName(comp: *Compilation, name: []const u8) ?FromName {
|
||||
if (fromNameExtra(name, .common)) |found| return found;
|
||||
switch (comp.target.cpu.arch) {
|
||||
.aarch64, .aarch64_be => if (fromNameExtra(name, .aarch64)) |found| return found,
|
||||
.amdgcn => if (fromNameExtra(name, .amdgcn)) |found| return found,
|
||||
.arm, .armeb, .thumb, .thumbeb => if (fromNameExtra(name, .arm)) |found| return found,
|
||||
.bpfeb, .bpfel => if (fromNameExtra(name, .bpf)) |found| return found,
|
||||
.hexagon => if (fromNameExtra(name, .hexagon)) |found| return found,
|
||||
.loongarch32, .loongarch64 => if (fromNameExtra(name, .loongarch)) |found| return found,
|
||||
.mips64, .mips64el, .mips, .mipsel => if (fromNameExtra(name, .mips)) |found| return found,
|
||||
.nvptx, .nvptx64 => if (fromNameExtra(name, .nvptx)) |found| return found,
|
||||
.powerpc64, .powerpc64le, .powerpc, .powerpcle => if (fromNameExtra(name, .powerpc)) |found| return found,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => if (fromNameExtra(name, .riscv)) |found| return found,
|
||||
.s390x => if (fromNameExtra(name, .s390x)) |found| return found,
|
||||
.ve => if (fromNameExtra(name, .ve)) |found| return found,
|
||||
.xcore => if (fromNameExtra(name, .xcore)) |found| return found,
|
||||
.x86_64 => {
|
||||
if (fromNameExtra(name, .x86_64)) |found| return found;
|
||||
if (fromNameExtra(name, .x86)) |found| return found;
|
||||
},
|
||||
.x86 => if (fromNameExtra(name, .x86)) |found| return found,
|
||||
else => {},
|
||||
test Iterator {
|
||||
var it = Iterator{};
|
||||
|
||||
var seen = std.StringHashMap(Builtin).init(std.testing.allocator);
|
||||
defer seen.deinit();
|
||||
|
||||
var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_state.deinit();
|
||||
const arena = arena_state.allocator();
|
||||
|
||||
while (it.next()) |entry| {
|
||||
const index = Builtin.uniqueIndex(entry.name).?;
|
||||
var buf: [Builtin.longest_name]u8 = undefined;
|
||||
const name_from_index = Builtin.nameFromUniqueIndex(index, &buf);
|
||||
try std.testing.expectEqualStrings(entry.name, name_from_index);
|
||||
|
||||
if (seen.contains(entry.name)) {
|
||||
std.debug.print("iterated over {s} twice\n", .{entry.name});
|
||||
std.debug.print("current data: {}\n", .{entry.builtin});
|
||||
std.debug.print("previous data: {}\n", .{seen.get(entry.name).?});
|
||||
return error.TestExpectedUniqueEntries;
|
||||
}
|
||||
try seen.put(try arena.dupe(u8, entry.name), entry.builtin);
|
||||
}
|
||||
return null;
|
||||
try std.testing.expectEqual(@as(usize, Builtin.data.len), seen.count());
|
||||
}
|
||||
|
||||
fn fromNameExtra(name: []const u8, comptime arch: std.meta.Tag(Tag)) ?FromName {
|
||||
const list = @field(@This(), @tagName(arch));
|
||||
const tag = list.tagFromName(name) orelse return null;
|
||||
const builtin = list.data[@intFromEnum(tag)];
|
||||
test "All builtins" {
|
||||
var comp = Compilation.init(std.testing.allocator, std.fs.cwd());
|
||||
defer comp.deinit();
|
||||
_ = try comp.generateBuiltinMacros(.include_system_defines);
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
return .{
|
||||
.tag = @unionInit(Tag, @tagName(arch), tag),
|
||||
.param_str = builtin.param_str,
|
||||
.header = builtin.header,
|
||||
.language = builtin.language,
|
||||
.attributes = builtin.attributes,
|
||||
.features = if (@hasField(@TypeOf(builtin), "features")) builtin.features else null,
|
||||
};
|
||||
}
|
||||
const type_arena = arena.allocator();
|
||||
|
||||
test "all builtins" {
|
||||
const list_names = comptime std.meta.fieldNames(Tag);
|
||||
inline for (list_names) |list_name| {
|
||||
const list = @field(Builtins, list_name);
|
||||
for (list.data, 0..) |builtin, index| {
|
||||
{
|
||||
var it = TypeDescription.TypeIterator.init(builtin.param_str);
|
||||
while (it.next()) |_| {}
|
||||
}
|
||||
if (@hasField(@TypeOf(builtin), "features")) {
|
||||
const corrected_name = comptime if (std.mem.eql(u8, list_name, "x86_64")) "x86" else list_name;
|
||||
const features = &@field(std.Target, corrected_name).all_features;
|
||||
|
||||
const feature_string = builtin.features orelse continue;
|
||||
var it = std.mem.tokenizeAny(u8, std.mem.span(feature_string), "()|,");
|
||||
|
||||
outer: while (it.next()) |feature| {
|
||||
for (features) |valid_feature| {
|
||||
if (std.mem.eql(u8, feature, valid_feature.name)) continue :outer;
|
||||
}
|
||||
std.debug.panic("unknown feature {s} on {t}\n", .{ feature, @as(list.Tag, @enumFromInt(index)) });
|
||||
}
|
||||
}
|
||||
var builtin_it = Iterator{};
|
||||
while (builtin_it.next()) |entry| {
|
||||
const name = try type_arena.dupe(u8, entry.name);
|
||||
if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| {
|
||||
const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?;
|
||||
const found_by_lookup = comp.builtins.lookup(name);
|
||||
try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag);
|
||||
try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "Allocation failures" {
|
||||
const Test = struct {
|
||||
fn testOne(allocator: std.mem.Allocator) !void {
|
||||
var comp = Compilation.init(allocator, std.fs.cwd());
|
||||
defer comp.deinit();
|
||||
_ = try comp.generateBuiltinMacros(.include_system_defines);
|
||||
var arena = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena.deinit();
|
||||
|
||||
const type_arena = arena.allocator();
|
||||
|
||||
const num_builtins = 40;
|
||||
var builtin_it = Iterator{};
|
||||
for (0..num_builtins) |_| {
|
||||
const entry = builtin_it.next().?;
|
||||
_ = try comp.builtins.getOrCreate(&comp, entry.name, type_arena);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{});
|
||||
}
|
||||
|
||||
13146
lib/compiler/aro/aro/Builtins/Builtin.zig
vendored
Normal file
13146
lib/compiler/aro/aro/Builtins/Builtin.zig
vendored
Normal file
File diff suppressed because it is too large
Load Diff
143
lib/compiler/aro/aro/Builtins/Properties.zig
vendored
Normal file
143
lib/compiler/aro/aro/Builtins/Properties.zig
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Properties = @This();
|
||||
|
||||
param_str: []const u8,
|
||||
language: Language = .all_languages,
|
||||
attributes: Attributes = Attributes{},
|
||||
header: Header = .none,
|
||||
target_set: TargetSet = TargetSet.initOne(.basic),
|
||||
|
||||
/// Header which must be included for a builtin to be available
|
||||
pub const Header = enum {
|
||||
none,
|
||||
/// stdio.h
|
||||
stdio,
|
||||
/// stdlib.h
|
||||
stdlib,
|
||||
/// setjmpex.h
|
||||
setjmpex,
|
||||
/// stdarg.h
|
||||
stdarg,
|
||||
/// string.h
|
||||
string,
|
||||
/// ctype.h
|
||||
ctype,
|
||||
/// wchar.h
|
||||
wchar,
|
||||
/// setjmp.h
|
||||
setjmp,
|
||||
/// malloc.h
|
||||
malloc,
|
||||
/// strings.h
|
||||
strings,
|
||||
/// unistd.h
|
||||
unistd,
|
||||
/// pthread.h
|
||||
pthread,
|
||||
/// math.h
|
||||
math,
|
||||
/// complex.h
|
||||
complex,
|
||||
/// Blocks.h
|
||||
blocks,
|
||||
};
|
||||
|
||||
/// Languages in which a builtin is available
|
||||
pub const Language = enum {
|
||||
all_languages,
|
||||
all_ms_languages,
|
||||
all_gnu_languages,
|
||||
gnu_lang,
|
||||
};
|
||||
|
||||
pub const Attributes = packed struct {
|
||||
/// Function does not return
|
||||
noreturn: bool = false,
|
||||
|
||||
/// Function has no side effects
|
||||
pure: bool = false,
|
||||
|
||||
/// Function has no side effects and does not read memory
|
||||
@"const": bool = false,
|
||||
|
||||
/// Signature is meaningless; use custom typecheck
|
||||
custom_typecheck: bool = false,
|
||||
|
||||
/// A declaration of this builtin should be recognized even if the type doesn't match the specified signature.
|
||||
allow_type_mismatch: bool = false,
|
||||
|
||||
/// this is a libc/libm function with a '__builtin_' prefix added.
|
||||
lib_function_with_builtin_prefix: bool = false,
|
||||
|
||||
/// this is a libc/libm function without a '__builtin_' prefix. This builtin is disableable by '-fno-builtin-foo'
|
||||
lib_function_without_prefix: bool = false,
|
||||
|
||||
/// Function returns twice (e.g. setjmp)
|
||||
returns_twice: bool = false,
|
||||
|
||||
/// Nature of the format string passed to this function
|
||||
format_kind: enum(u3) {
|
||||
/// Does not take a format string
|
||||
none,
|
||||
/// this is a printf-like function whose Nth argument is the format string
|
||||
printf,
|
||||
/// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis
|
||||
vprintf,
|
||||
/// this is a scanf-like function whose Nth argument is the format string
|
||||
scanf,
|
||||
/// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis
|
||||
vscanf,
|
||||
} = .none,
|
||||
|
||||
/// Position of format string argument. Only meaningful if format_kind is not .none
|
||||
format_string_position: u5 = 0,
|
||||
|
||||
/// if false, arguments are not evaluated
|
||||
eval_args: bool = true,
|
||||
|
||||
/// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored
|
||||
const_without_errno_and_fp_exceptions: bool = false,
|
||||
|
||||
/// no side effects and does not read memory, but only when FP exceptions are ignored
|
||||
const_without_fp_exceptions: bool = false,
|
||||
|
||||
/// this function can be constant evaluated by the frontend
|
||||
const_evaluable: bool = false,
|
||||
};
|
||||
|
||||
pub const Target = enum {
|
||||
/// Supported on all targets
|
||||
basic,
|
||||
aarch64,
|
||||
aarch64_neon_sve_bridge,
|
||||
aarch64_neon_sve_bridge_cg,
|
||||
amdgpu,
|
||||
arm,
|
||||
bpf,
|
||||
hexagon,
|
||||
hexagon_dep,
|
||||
hexagon_map_custom_dep,
|
||||
loong_arch,
|
||||
mips,
|
||||
neon,
|
||||
nvptx,
|
||||
ppc,
|
||||
riscv,
|
||||
riscv_vector,
|
||||
sve,
|
||||
systemz,
|
||||
ve,
|
||||
vevl_gen,
|
||||
webassembly,
|
||||
x86,
|
||||
x86_64,
|
||||
xcore,
|
||||
};
|
||||
|
||||
/// Targets for which a builtin is enabled
|
||||
pub const TargetSet = std.enums.EnumSet(Target);
|
||||
|
||||
pub fn isVarArgs(properties: Properties) bool {
|
||||
return properties.param_str[properties.param_str.len - 1] == '.';
|
||||
}
|
||||
@ -13,10 +13,10 @@ pub const Component = union(enum) {
|
||||
};
|
||||
|
||||
pub const ComponentIterator = struct {
|
||||
str: [*:0]const u8,
|
||||
str: []const u8,
|
||||
idx: usize,
|
||||
|
||||
pub fn init(str: [*:0]const u8) ComponentIterator {
|
||||
pub fn init(str: []const u8) ComponentIterator {
|
||||
return .{
|
||||
.str = str,
|
||||
.idx = 0,
|
||||
@ -30,8 +30,8 @@ pub const ComponentIterator = struct {
|
||||
}
|
||||
|
||||
pub fn next(self: *ComponentIterator) ?Component {
|
||||
if (self.idx == self.str.len) return null;
|
||||
const c = self.str[self.idx];
|
||||
if (c == 0) return null;
|
||||
self.idx += 1;
|
||||
switch (c) {
|
||||
'L' => {
|
||||
@ -68,14 +68,18 @@ pub const ComponentIterator = struct {
|
||||
'z' => return .{ .spec = .z },
|
||||
'w' => return .{ .spec = .w },
|
||||
'F' => return .{ .spec = .F },
|
||||
'G' => return .{ .spec = .G },
|
||||
'H' => return .{ .spec = .H },
|
||||
'M' => return .{ .spec = .M },
|
||||
'a' => return .{ .spec = .a },
|
||||
'A' => return .{ .spec = .A },
|
||||
'V', 'E' => {
|
||||
'V', 'q', 'E' => {
|
||||
const start = self.idx;
|
||||
while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {}
|
||||
const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable;
|
||||
return switch (c) {
|
||||
'V' => .{ .spec = .{ .V = count } },
|
||||
'q' => .{ .spec = .{ .q = count } },
|
||||
'E' => .{ .spec = .{ .E = count } },
|
||||
else => unreachable,
|
||||
};
|
||||
@ -99,12 +103,16 @@ pub const ComponentIterator = struct {
|
||||
'p' => return .{ .spec = .p },
|
||||
'.' => {
|
||||
// can only appear at end of param string; indicates varargs function
|
||||
std.debug.assert(self.str[self.idx] == 0);
|
||||
std.debug.assert(self.idx == self.str.len);
|
||||
return null;
|
||||
},
|
||||
'!' => {
|
||||
std.debug.assert(self.str.len == 1);
|
||||
return .{ .spec = .@"!" };
|
||||
},
|
||||
|
||||
'*' => {
|
||||
if (std.ascii.isDigit(self.str[self.idx])) {
|
||||
if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) {
|
||||
defer self.idx += 1;
|
||||
const addr_space = self.str[self.idx] - '0';
|
||||
return .{ .suffix = .{ .@"*" = addr_space } };
|
||||
@ -115,14 +123,6 @@ pub const ComponentIterator = struct {
|
||||
'C' => return .{ .suffix = .C },
|
||||
'D' => return .{ .suffix = .D },
|
||||
'R' => return .{ .suffix = .R },
|
||||
'Q' => {
|
||||
defer self.idx += 1;
|
||||
switch (self.str[self.idx]) {
|
||||
'a' => return .{ .spec = .{ .Q = .aarch64_svcount_t } },
|
||||
'b' => return .{ .spec = .{ .Q = .amdgpu_buffer_rsrc_t } },
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
return null;
|
||||
@ -130,13 +130,13 @@ pub const ComponentIterator = struct {
|
||||
};
|
||||
|
||||
pub const TypeIterator = struct {
|
||||
param_str: [*:0]const u8,
|
||||
param_str: []const u8,
|
||||
prefix: [4]Prefix,
|
||||
spec: Spec,
|
||||
suffix: [4]Suffix,
|
||||
idx: usize,
|
||||
|
||||
pub fn init(param_str: [*:0]const u8) TypeIterator {
|
||||
pub fn init(param_str: []const u8) TypeIterator {
|
||||
return .{
|
||||
.param_str = param_str,
|
||||
.prefix = undefined,
|
||||
@ -176,7 +176,7 @@ pub const TypeIterator = struct {
|
||||
_ = it.next();
|
||||
}
|
||||
if (maybe_spec) |spec| {
|
||||
return .{
|
||||
return TypeDescription{
|
||||
.prefix = self.prefix[0..prefix_count],
|
||||
.spec = spec,
|
||||
.suffix = self.suffix[0..suffix_count],
|
||||
@ -236,17 +236,20 @@ const Spec = union(enum) {
|
||||
w,
|
||||
/// constant CFString
|
||||
F,
|
||||
/// id
|
||||
G,
|
||||
/// SEL
|
||||
H,
|
||||
/// struct objc_super
|
||||
M,
|
||||
/// __builtin_va_list
|
||||
a,
|
||||
/// "reference" to __builtin_va_list
|
||||
A,
|
||||
/// Vector, followed by the number of elements and the base type.
|
||||
V: u32,
|
||||
/// target builtin type, followed by a character to distinguish the builtin type
|
||||
Q: enum {
|
||||
aarch64_svcount_t,
|
||||
amdgpu_buffer_rsrc_t,
|
||||
},
|
||||
/// Scalable vector, followed by the number of elements and the base type.
|
||||
q: u32,
|
||||
/// ext_vector, followed by the number of elements and the base type.
|
||||
E: u32,
|
||||
/// _Complex, followed by the base type.
|
||||
@ -267,6 +270,8 @@ const Spec = union(enum) {
|
||||
K,
|
||||
/// pid_t
|
||||
p,
|
||||
/// Used to indicate a builtin with target-dependent param types. Must appear by itself
|
||||
@"!",
|
||||
};
|
||||
|
||||
const Suffix = union(enum) {
|
||||
|
||||
1150
lib/compiler/aro/aro/Builtins/aarch64.zig
vendored
1150
lib/compiler/aro/aro/Builtins/aarch64.zig
vendored
File diff suppressed because it is too large
Load Diff
2851
lib/compiler/aro/aro/Builtins/amdgcn.zig
vendored
2851
lib/compiler/aro/aro/Builtins/amdgcn.zig
vendored
File diff suppressed because it is too large
Load Diff
1076
lib/compiler/aro/aro/Builtins/arm.zig
vendored
1076
lib/compiler/aro/aro/Builtins/arm.zig
vendored
File diff suppressed because it is too large
Load Diff
231
lib/compiler/aro/aro/Builtins/bpf.zig
vendored
231
lib/compiler/aro/aro/Builtins/bpf.zig
vendored
@ -1,231 +0,0 @@
|
||||
//! Autogenerated by GenerateDef from src/aro/Builtins/bpf.def, do not edit
|
||||
// zig fmt: off
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn with(comptime Properties: type) type {
|
||||
return struct {
|
||||
|
||||
/// Integer starting at 0 derived from the unique index,
|
||||
/// corresponds with the data array index.
|
||||
pub const Tag = enum(u16) { __builtin_btf_type_id,
|
||||
__builtin_preserve_enum_value,
|
||||
__builtin_preserve_field_info,
|
||||
__builtin_preserve_type_info,
|
||||
};
|
||||
|
||||
pub fn fromName(name: []const u8) ?Properties {
|
||||
const data_index = tagFromName(name) orelse return null;
|
||||
return data[@intFromEnum(data_index)];
|
||||
}
|
||||
|
||||
pub fn tagFromName(name: []const u8) ?Tag {
|
||||
const unique_index = uniqueIndex(name) orelse return null;
|
||||
return @enumFromInt(unique_index - 1);
|
||||
}
|
||||
|
||||
pub fn fromTag(tag: Tag) Properties {
|
||||
return data[@intFromEnum(tag)];
|
||||
}
|
||||
|
||||
pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 {
|
||||
std.debug.assert(name_buf.len >= longest_name);
|
||||
const unique_index = @intFromEnum(tag) + 1;
|
||||
return nameFromUniqueIndex(unique_index, name_buf);
|
||||
}
|
||||
|
||||
pub fn nameFromTag(tag: Tag) NameBuf {
|
||||
var name_buf: NameBuf = undefined;
|
||||
const unique_index = @intFromEnum(tag) + 1;
|
||||
const name = nameFromUniqueIndex(unique_index, &name_buf.buf);
|
||||
name_buf.len = @intCast(name.len);
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
pub const NameBuf = struct {
|
||||
buf: [longest_name]u8 = undefined,
|
||||
len: std.math.IntFittingRange(0, longest_name),
|
||||
|
||||
pub fn span(self: *const NameBuf) []const u8 {
|
||||
return self.buf[0..self.len];
|
||||
}
|
||||
};
|
||||
|
||||
pub fn exists(name: []const u8) bool {
|
||||
if (name.len < shortest_name or name.len > longest_name) return false;
|
||||
|
||||
var index: u16 = 0;
|
||||
for (name) |c| {
|
||||
index = findInList(dafsa[index].child_index, c) orelse return false;
|
||||
}
|
||||
return dafsa[index].end_of_word;
|
||||
}
|
||||
|
||||
pub const shortest_name = 21;
|
||||
pub const longest_name = 29;
|
||||
|
||||
/// Search siblings of `first_child_index` for the `char`
|
||||
/// If found, returns the index of the node within the `dafsa` array.
|
||||
/// Otherwise, returns `null`.
|
||||
pub fn findInList(first_child_index: u16, char: u8) ?u16 {
|
||||
@setEvalBranchQuota(8);
|
||||
var index = first_child_index;
|
||||
while (true) {
|
||||
if (dafsa[index].char == char) return index;
|
||||
if (dafsa[index].end_of_list) return null;
|
||||
index += 1;
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`,
|
||||
/// or null if the name was not found.
|
||||
pub fn uniqueIndex(name: []const u8) ?u16 {
|
||||
if (name.len < shortest_name or name.len > longest_name) return null;
|
||||
|
||||
var index: u16 = 0;
|
||||
var node_index: u16 = 0;
|
||||
|
||||
for (name) |c| {
|
||||
const child_index = findInList(dafsa[node_index].child_index, c) orelse return null;
|
||||
var sibling_index = dafsa[node_index].child_index;
|
||||
while (true) {
|
||||
const sibling_c = dafsa[sibling_index].char;
|
||||
std.debug.assert(sibling_c != 0);
|
||||
if (sibling_c < c) {
|
||||
index += dafsa[sibling_index].number;
|
||||
}
|
||||
if (dafsa[sibling_index].end_of_list) break;
|
||||
sibling_index += 1;
|
||||
}
|
||||
node_index = child_index;
|
||||
if (dafsa[node_index].end_of_word) index += 1;
|
||||
}
|
||||
|
||||
if (!dafsa[node_index].end_of_word) return null;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/// Returns a slice of `buf` with the name associated with the given `index`.
|
||||
/// This function should only be called with an `index` that
|
||||
/// is already known to exist within the `dafsa`, e.g. an index
|
||||
/// returned from `uniqueIndex`.
|
||||
pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 {
|
||||
std.debug.assert(index >= 1 and index <= data.len);
|
||||
|
||||
var node_index: u16 = 0;
|
||||
var count: u16 = index;
|
||||
var w = std.Io.Writer.fixed(buf);
|
||||
|
||||
while (true) {
|
||||
var sibling_index = dafsa[node_index].child_index;
|
||||
while (true) {
|
||||
if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) {
|
||||
count -= dafsa[sibling_index].number;
|
||||
} else {
|
||||
w.writeByte(dafsa[sibling_index].char) catch unreachable;
|
||||
node_index = sibling_index;
|
||||
if (dafsa[node_index].end_of_word) {
|
||||
count -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (dafsa[sibling_index].end_of_list) break;
|
||||
sibling_index += 1;
|
||||
}
|
||||
if (count == 0) break;
|
||||
}
|
||||
|
||||
return w.buffered();
|
||||
}
|
||||
|
||||
const Node = packed struct {
|
||||
char: u8,
|
||||
/// Nodes are numbered with "an integer which gives the number of words that
|
||||
/// would be accepted by the automaton starting from that state." This numbering
|
||||
/// allows calculating "a one-to-one correspondence between the integers 1 to L
|
||||
/// (L is the number of words accepted by the automaton) and the words themselves."
|
||||
///
|
||||
/// Essentially, this allows us to have a minimal perfect hashing scheme such that
|
||||
/// it's possible to store & lookup the properties of each builtin using a separate array.
|
||||
number: std.math.IntFittingRange(0, data.len),
|
||||
/// If true, this node is the end of a valid builtin.
|
||||
/// Note: This does not necessarily mean that this node does not have child nodes.
|
||||
end_of_word: bool,
|
||||
/// If true, this node is the end of a sibling list.
|
||||
/// If false, then (index + 1) will contain the next sibling.
|
||||
end_of_list: bool,
|
||||
/// Index of the first child of this node.
|
||||
child_index: u16,
|
||||
};
|
||||
|
||||
const dafsa = [_]Node{
|
||||
.{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3 },
|
||||
.{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4 },
|
||||
.{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 5 },
|
||||
.{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 6 },
|
||||
.{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 7 },
|
||||
.{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 8 },
|
||||
.{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 9 },
|
||||
.{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 10 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 11 },
|
||||
.{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 13 },
|
||||
.{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 14 },
|
||||
.{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 15 },
|
||||
.{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 16 },
|
||||
.{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 17 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 18 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 19 },
|
||||
.{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 20 },
|
||||
.{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 21 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 22 },
|
||||
.{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 23 },
|
||||
.{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 24 },
|
||||
.{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 25 },
|
||||
.{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 26 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 27 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 28 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 29 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 30 },
|
||||
.{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 33 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 34 },
|
||||
.{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 35 },
|
||||
.{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 36 },
|
||||
.{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
|
||||
.{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 37 },
|
||||
.{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 38 },
|
||||
.{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 39 },
|
||||
.{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 40 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 41 },
|
||||
.{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 42 },
|
||||
.{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 43 },
|
||||
.{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 44 },
|
||||
.{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 45 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 46 },
|
||||
.{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 45 },
|
||||
.{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 47 },
|
||||
.{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 48 },
|
||||
.{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 49 },
|
||||
.{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 50 },
|
||||
.{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 51 },
|
||||
.{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 52 },
|
||||
.{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 53 },
|
||||
.{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 54 },
|
||||
.{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
|
||||
.{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
|
||||
};
|
||||
pub const data = blk: {
|
||||
@setEvalBranchQuota(36);
|
||||
break :blk [_]Properties{
|
||||
.{ .param_str = "LUi.", .attributes = .{ .custom_typecheck = true } },
|
||||
.{ .param_str = "Li.", .attributes = .{ .custom_typecheck = true } },
|
||||
.{ .param_str = "Ui.", .attributes = .{ .custom_typecheck = true } },
|
||||
.{ .param_str = "LUi.", .attributes = .{ .custom_typecheck = true } },
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
5527
lib/compiler/aro/aro/Builtins/common.zig
vendored
5527
lib/compiler/aro/aro/Builtins/common.zig
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user