authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-23 17:04:26-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-23 17:04:26-05:00
logc00216701c64269a2395e84f3ccff99d6fb89ffc
tree9fa071b9e96f9eadc5069b71634b11fc13b00839
parentc21884e1d64e4193e03be4f3064917a26b34b142
parent45081c1e9cc28757cb563c77553631f7a92b29d8

Merge remote-tracking branch 'origin/master' into llvm8


124 files changed, 6574 insertions(+), 1880 deletions(-)

.builds/freebsd.yml created+22
......@@ -0,0 +1,22 @@
1arch: x86_64
2image: freebsd
3packages:
4 - cmake
5 - ninja
6 - llvm70
7sources:
8 - https://github.com/ziglang/zig.git
9tasks:
10 - build: |
11 cd zig && mkdir build && cd build
12 cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
13 ninja install
14 - test: |
15 cd zig/build
16 bin/zig test ../test/behavior.zig
17 # TODO enable all tests
18 #bin/zig build --build-file ../build.zig test
19 # TODO integrate with the download page updater and make a
20 # static build available to download for FreeBSD.
21 # This will require setting up a cache of LLVM/Clang built
22 # statically.
CMakeLists.txt+16
......@@ -444,6 +444,7 @@ set(ZIG_STD_FILES
444444 "buffer.zig"
445445 "build.zig"
446446 "c/darwin.zig"
447 "c/freebsd.zig"
447448 "c/index.zig"
448449 "c/linux.zig"
449450 "c/windows.zig"
......@@ -490,6 +491,7 @@ set(ZIG_STD_FILES
490491 "heap.zig"
491492 "index.zig"
492493 "io.zig"
494 "io/seekable_stream.zig"
493495 "json.zig"
494496 "lazy_init.zig"
495497 "linked_list.zig"
......@@ -582,6 +584,10 @@ set(ZIG_STD_FILES
582584 "os/linux/vdso.zig"
583585 "os/linux/x86_64.zig"
584586 "os/linux/arm64.zig"
587 "os/freebsd/errno.zig"
588 "os/freebsd/index.zig"
589 "os/freebsd/syscall.zig"
590 "os/freebsd/x86_64.zig"
585591 "os/path.zig"
586592 "os/time.zig"
587593 "os/windows/advapi32.zig"
......@@ -617,6 +623,16 @@ set(ZIG_STD_FILES
617623 "special/compiler_rt/fixunstfdi.zig"
618624 "special/compiler_rt/fixunstfsi.zig"
619625 "special/compiler_rt/fixunstfti.zig"
626 "special/compiler_rt/fixint.zig"
627 "special/compiler_rt/fixdfdi.zig"
628 "special/compiler_rt/fixdfsi.zig"
629 "special/compiler_rt/fixdfti.zig"
630 "special/compiler_rt/fixsfdi.zig"
631 "special/compiler_rt/fixsfsi.zig"
632 "special/compiler_rt/fixsfti.zig"
633 "special/compiler_rt/fixtfdi.zig"
634 "special/compiler_rt/fixtfsi.zig"
635 "special/compiler_rt/fixtfti.zig"
620636 "special/compiler_rt/floattidf.zig"
621637 "special/compiler_rt/floattisf.zig"
622638 "special/compiler_rt/floattitf.zig"
README.md+71-30
......@@ -42,33 +42,71 @@ clarity.
4242 * In addition to creating executables, creating a C library is a primary use
4343 case. You can export an auto-generated .h file.
4444
45### Support Table
46
47Freestanding means that you do not directly interact with the OS
48or you are writing your own OS.
49
50Note that if you use libc or other libraries to interact with the OS,
51that counts as "freestanding" for the purposes of this table.
52
53| | freestanding | linux | macosx | windows | other |
54|-------------|--------------|---------|---------|---------|---------|
55|i386 | OK | planned | OK | planned | planned |
56|x86_64 | OK | OK | OK | OK | planned |
57|arm | OK | planned | planned | planned | planned |
58|bpf | OK | planned | N/A | N/A | planned |
59|hexagon | OK | planned | N/A | N/A | planned |
60|mips | OK | planned | N/A | N/A | planned |
61|powerpc | OK | planned | N/A | N/A | planned |
62|r600 | OK | planned | N/A | N/A | planned |
63|amdgcn | OK | planned | N/A | N/A | planned |
64|sparc | OK | planned | N/A | N/A | planned |
65|s390x | OK | planned | N/A | N/A | planned |
66|spir | OK | planned | N/A | N/A | planned |
67|lanai | OK | planned | N/A | N/A | planned |
68|wasm32 | planned | N/A | N/A | N/A | N/A |
69|wasm64 | planned | N/A | N/A | N/A | N/A |
70|riscv32 | planned | planned | N/A | N/A | planned |
71|riscv64 | planned | planned | N/A | N/A | planned |
45### Supported Targets
46
47#### Tier 1 Support
48
49 * Not only can Zig generate machine code for these targets, but the standard
50 library cross-platform abstractions have implementations for these targets.
51 Thus it is practical to write a pure Zig application with no dependency on
52 libc.
53 * The CI server automatically tests these targets on every commit to master
54 branch, and updates ziglang.org/download with links to pre-built binaries.
55 * These targets have debug info capabilities and therefore produce stack
56 traces on failed assertions.
57
58#### Tier 2 Support
59
60 * There may be some standard library implementations, but many abstractions
61 will give an "Unsupported OS" compile error. One can link with libc or other
62 libraries to fill in the gaps in the standard library.
63 * These targets are known to work, but are not automatically tested, so there
64 are occasional regressions.
65 * Some tests may be disabled for these targets as we work toward Tier 1
66 support.
67
68#### Tier 3 Support
69
70 * The standard library has little to no knowledge of the existence of this
71 target.
72 * Because Zig is based on LLVM, it has the capability to build for these
73 targets, and LLVM has the target enabled by default.
74 * These targets are not frequently tested; one will likely need to contribute
75 to Zig in order to build for these targets.
76 * The Zig compiler might need to be updated with a few things such as
77 - what sizes are the C integer types
78 - C ABI calling convention for this target
79 - bootstrap code and default panic handler
80
81#### Tier 4 Support
82
83 * Support for these targets is entirely experimental.
84 * LLVM may have the target as an experimental target, which means that you
85 need to use Zig-provided binaries for the target to be available, or
86 build LLVM from source with special configure flags.
87
88#### Support Table
89
90| | freestanding | linux | macosx | windows | freebsd | other |
91|--------|--------------|--------|--------|---------|---------|--------|
92|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 3 |
93|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 |
94|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
95|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
96|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
97|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
98|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
99|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
100|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
101|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
102|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
103|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
104|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
105|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 |
106|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A |
107|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A |
108|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 |
109|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 |
72110
73111## Community
74112
......@@ -133,7 +171,8 @@ See https://github.com/ziglang/zig/wiki/Building-Zig-on-Windows
133171*Note: Stage 2 compiler is not complete. Beta users of Zig should use the
134172Stage 1 compiler for now.*
135173
136Dependencies are the same as Stage 1, except now you have a working zig compiler.
174Dependencies are the same as Stage 1, except now you can use stage 1 to compile
175Zig code.
137176
138177```
139178bin/zig build --build-file ../build.zig --prefix $(pwd)/stage2 install
......@@ -145,11 +184,13 @@ binary.
145184
146185### Stage 3: Rebuild Self-Hosted Zig Using the Self-Hosted Compiler
147186
148This is the actual compiler binary that we will install to the system.
149
150187*Note: Stage 2 compiler is not yet able to build Stage 3. Building Stage 3 is
151188not yet supported.*
152189
190Once the self-hosted compiler can build itself, this will be the actual
191compiler binary that we will install to the system. Until then, users should
192use stage 1.
193
153194#### Debug / Development Build
154195
155196```
build.zig+1-1
......@@ -297,7 +297,7 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void {
297297 );
298298
299299 exe.linkSystemLibrary("pthread");
300 } else if (exe.target.isDarwin()) {
300 } else if (exe.target.isDarwin() or exe.target.isFreeBSD()) {
301301 if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "")) {
302302 // Compiler is GCC.
303303 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null);
ci/azure/linux_script+3
......@@ -34,6 +34,9 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
3434
3535 SHASUM=$(sha256sum $ARTIFACTSDIR/$TARBALL | cut '-d ' -f1)
3636 BYTESIZE=$(wc -c < $ARTIFACTSDIR/$TARBALL)
37 # `set -x` causes these variables to be mangled.
38 # See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
39 set +x
3740 echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
3841 echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
3942 echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
ci/azure/macos_script+3
......@@ -98,6 +98,9 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
9898
9999 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
100100 BYTESIZE=$(wc -c < $TARBALL)
101 # `set -x` causes these variables to be mangled.
102 # See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
103 set +x
101104 echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
102105 echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
103106 echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
ci/azure/windows_install+1
......@@ -3,6 +3,7 @@
33set -x
44set -e
55
6pacman -Su --needed --noconfirm
67pacman -S --needed --noconfirm wget p7zip python3-pip
78pip install s3cmd
89wget -nv "https://ziglang.org/deps/llvm%2bclang-8.0.0-win64-msvc-release.tar.xz"
ci/azure/windows_upload+3
......@@ -25,6 +25,9 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
2525
2626 SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1)
2727 BYTESIZE=$(wc -c < $TARBALL)
28 # `set -x` causes these variables to be mangled.
29 # See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
30 set +x
2831 echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
2932 echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
3033 echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
cmake/Findclang.cmake+2
......@@ -30,6 +30,7 @@ else()
3030 /usr/lib/llvm/8/include
3131 /usr/lib/llvm-8/include
3232 /usr/lib/llvm-8.0/include
33 /usr/local/llvm80/include
3334 /mingw64/include)
3435
3536 macro(FIND_AND_ADD_CLANG_LIB _libname_)
......@@ -40,6 +41,7 @@ else()
4041 /usr/lib/llvm/8/lib
4142 /usr/lib/llvm-8/lib
4243 /usr/lib/llvm-8.0/lib
44 /usr/local/llvm80/lib
4345 /mingw64/lib
4446 /c/msys64/mingw64/lib
4547 c:\\msys64\\mingw64\\lib)
cmake/Findlld.cmake+7-1
......@@ -9,9 +9,14 @@
99find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h
1010 PATHS
1111 /usr/lib/llvm-8.0/include
12 /usr/local/llvm80/include
1213 /mingw64/include)
1314
14find_library(LLD_LIBRARY NAMES lld-8.0 lld PATHS /usr/lib/llvm-8.0/lib)
15find_library(LLD_LIBRARY NAMES lld-8.0 lld80 lld
16 PATHS
17 /usr/lib/llvm-8.0/lib
18 /usr/local/llvm80/lib
19)
1520if(EXISTS ${LLD_LIBRARY})
1621 set(LLD_LIBRARIES ${LLD_LIBRARY})
1722else()
......@@ -20,6 +25,7 @@ else()
2025 find_library(LLD_${_prettylibname_}_LIB NAMES ${_libname_}
2126 PATHS
2227 /usr/lib/llvm-8.0/lib
28 /usr/local/llvm80/lib
2329 /mingw64/lib
2430 /c/msys64/mingw64/lib
2531 c:/msys64/mingw64/lib)
cmake/Findllvm.cmake+1-1
......@@ -8,7 +8,7 @@
88# LLVM_LIBDIRS
99
1010find_program(LLVM_CONFIG_EXE
11 NAMES llvm-config-8 llvm-config-8.0 llvm-config
11 NAMES llvm-config-8 llvm-config-8.0 llvm-config80 llvm-config
1212 PATHS
1313 "/mingw64/bin"
1414 "/c/msys64/mingw64/bin"
deps/lld/ELF/OutputSections.cpp+1-1
......@@ -95,7 +95,7 @@ void OutputSection::addSection(InputSection *IS) {
9595 Flags = IS->Flags;
9696 } else {
9797 // Otherwise, check if new type or flags are compatible with existing ones.
98 unsigned Mask = SHF_ALLOC | SHF_TLS | SHF_LINK_ORDER;
98 unsigned Mask = SHF_TLS | SHF_LINK_ORDER;
9999 if ((Flags & Mask) != (IS->Flags & Mask))
100100 error("incompatible section flags for " + Name + "\n>>> " + toString(IS) +
101101 ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name +
doc/langref.html.in+166-101
......@@ -8,7 +8,13 @@
88 body{
99 background-color:#111;
1010 color: #bbb;
11 font-family: sans-serif;
11 font-family: system-ui,
12 /* Fallbacks for browsers that don't support system-ui */
13 /* https://caniuse.com/#search=system-ui */
14 -apple-system, /* iOS and macOS */
15 Roboto, /* Android */
16 "Segoe UI", /* Windows */
17 sans-serif;
1218 }
1319 a {
1420 color: #88f;
......@@ -159,7 +165,7 @@ const std = @import("std");
159165
160166pub fn main() !void {
161167 // If this program is run without stdout attached, exit with an error.
162 var stdout_file = try std.io.getStdOut();
168 const stdout_file = try std.io.getStdOut();
163169 // If this program encounters pipe failure when printing to stdout, exit
164170 // with an error.
165171 try stdout_file.write("Hello, world!\n");
......@@ -3273,13 +3279,13 @@ const err = (error {FileNotFound}).FileNotFound;
32733279 This becomes useful when using {#link|Inferred Error Sets#}.
32743280 </p>
32753281 {#header_open|The Global Error Set#}
3276 <p>{#syntax#}error{#endsyntax#} refers to the global error set.
3282 <p>{#syntax#}anyerror{#endsyntax#} refers to the global error set.
32773283 This is the error set that contains all errors in the entire compilation unit.
32783284 It is a superset of all other error sets and a subset of none of them.
32793285 </p>
32803286 <p>
32813287 You can implicitly cast any error set to the global one, and you can explicitly
3282 cast an error of global error set to a non-global one. This inserts a language-level
3288 cast an error of the global error set to a non-global one. This inserts a language-level
32833289 assert to make sure the error value is in fact in the destination error set.
32843290 </p>
32853291 <p>
......@@ -4264,13 +4270,21 @@ fn foo() i32 {
42644270 return 1234;
42654271}
42664272 {#code_end#}
4267 <p>However, if the expression has type {#syntax#}void{#endsyntax#}:</p>
4273 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>
42684274 {#code_begin|test#}
4269test "ignoring expression value" {
4270 foo();
4275test "void is ignored" {
4276 returnsVoid();
4277}
4278
4279test "explicitly ignoring expression value" {
4280 _ = foo();
42714281}
42724282
4273fn foo() void {}
4283fn returnsVoid() void {}
4284
4285fn foo() i32 {
4286 return 1234;
4287}
42744288 {#code_end#}
42754289 {#header_close#}
42764290
......@@ -5155,6 +5169,34 @@ fn seq(c: u8) void {
51555169 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
51565170 </p>
51575171 {#header_close#}
5172 {#header_open|@alignCast#}
5173 <pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: var) var{#endsyntax#}</pre>
5174 <p>
5175 {#syntax#}ptr{#endsyntax#} can be {#syntax#}*T{#endsyntax#}, {#syntax#}fn(){#endsyntax#}, {#syntax#}?*T{#endsyntax#},
5176 {#syntax#}?fn(){#endsyntax#}, or {#syntax#}[]T{#endsyntax#}. It returns the same type as {#syntax#}ptr{#endsyntax#}
5177 except with the alignment adjusted to the new value.
5178 </p>
5179 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
5180 to the generated code to make sure the pointer is aligned as promised.</p>
5181
5182 {#header_close#}
5183 {#header_open|@alignOf#}
5184 <pre>{#syntax#}@alignOf(comptime T: type) comptime_int{#endsyntax#}</pre>
5185 <p>
5186 This function returns the number of bytes that this type should be aligned to
5187 for the current target to match the C ABI. When the child type of a pointer has
5188 this alignment, the alignment can be omitted from the type.
5189 </p>
5190 <pre>{#syntax#}const assert = @import("std").debug.assert;
5191comptime {
5192 assert(*u32 == *align(@alignOf(u32)) u32);
5193}{#endsyntax#}</pre>
5194 <p>
5195 The result is a target-specific compile time constant. It is guaranteed to be
5196 less than or equal to {#link|@sizeOf(T)|@sizeOf#}.
5197 </p>
5198 {#see_also|Alignment#}
5199 {#header_close#}
51585200 {#header_open|@ArgType#}
51595201 <pre>{#syntax#}@ArgType(comptime T: type, comptime n: usize) type{#endsyntax#}</pre>
51605202 <p>
......@@ -5227,6 +5269,7 @@ fn seq(c: u8) void {
52275269 Works at compile-time if {#syntax#}value{#endsyntax#} is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works.
52285270 </p>
52295271 {#header_close#}
5272
52305273 {#header_open|@bitOffsetOf#}
52315274 <pre>{#syntax#}@bitOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int{#endsyntax#}</pre>
52325275 <p>
......@@ -5239,6 +5282,19 @@ fn seq(c: u8) void {
52395282 </p>
52405283 {#see_also|@byteOffsetOf#}
52415284 {#header_close#}
5285
5286 {#header_open|@boolToInt#}
5287 <pre>{#syntax#}@boolToInt(value: bool) u1{#endsyntax#}</pre>
5288 <p>
5289 Converts {#syntax#}true{#endsyntax#} to {#syntax#}u1(1){#endsyntax#} and {#syntax#}false{#endsyntax#} to
5290 {#syntax#}u1(0){#endsyntax#}.
5291 </p>
5292 <p>
5293 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#}
5294 instead of {#syntax#}u1{#endsyntax#}.
5295 </p>
5296 {#header_close#}
5297
52425298 {#header_open|@breakpoint#}
52435299 <pre>{#syntax#}@breakpoint(){#endsyntax#}</pre>
52445300 <p>
......@@ -5250,52 +5306,22 @@ fn seq(c: u8) void {
52505306 </p>
52515307
52525308 {#header_close#}
5253 {#header_open|@byteOffsetOf#}
5254 <pre>{#syntax#}@byteOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int{#endsyntax#}</pre>
5255 <p>
5256 Returns the byte offset of a field relative to its containing struct.
5257 </p>
5258 {#see_also|@bitOffsetOf#}
5259 {#header_close#}
5260 {#header_open|@alignCast#}
5261 <pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: var) var{#endsyntax#}</pre>
5262 <p>
5263 {#syntax#}ptr{#endsyntax#} can be {#syntax#}*T{#endsyntax#}, {#syntax#}fn(){#endsyntax#}, {#syntax#}?*T{#endsyntax#},
5264 {#syntax#}?fn(){#endsyntax#}, or {#syntax#}[]T{#endsyntax#}. It returns the same type as {#syntax#}ptr{#endsyntax#}
5265 except with the alignment adjusted to the new value.
5266 </p>
5267 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
5268 to the generated code to make sure the pointer is aligned as promised.</p>
52695309
5270 {#header_close#}
5271 {#header_open|@alignOf#}
5272 <pre>{#syntax#}@alignOf(comptime T: type) comptime_int{#endsyntax#}</pre>
5310 {#header_open|@bswap#}
5311 <pre>{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}</pre>
5312 <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p>
52735313 <p>
5274 This function returns the number of bytes that this type should be aligned to
5275 for the current target to match the C ABI. When the child type of a pointer has
5276 this alignment, the alignment can be omitted from the type.
5277 </p>
5278 <pre>{#syntax#}const assert = @import("std").debug.assert;
5279comptime {
5280 assert(*u32 == *align(@alignOf(u32)) u32);
5281}{#endsyntax#}</pre>
5282 <p>
5283 The result is a target-specific compile time constant. It is guaranteed to be
5284 less than or equal to {#link|@sizeOf(T)|@sizeOf#}.
5314 Swaps the byte order of the integer. This converts a big endian integer to a little endian integer,
5315 and converts a little endian integer to a big endian integer.
52855316 </p>
5286 {#see_also|Alignment#}
52875317 {#header_close#}
52885318
5289 {#header_open|@boolToInt#}
5290 <pre>{#syntax#}@boolToInt(value: bool) u1{#endsyntax#}</pre>
5291 <p>
5292 Converts {#syntax#}true{#endsyntax#} to {#syntax#}u1(1){#endsyntax#} and {#syntax#}false{#endsyntax#} to
5293 {#syntax#}u1(0){#endsyntax#}.
5294 </p>
5319 {#header_open|@byteOffsetOf#}
5320 <pre>{#syntax#}@byteOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int{#endsyntax#}</pre>
52955321 <p>
5296 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#}
5297 instead of {#syntax#}u1{#endsyntax#}.
5322 Returns the byte offset of a field relative to its containing struct.
52985323 </p>
5324 {#see_also|@bitOffsetOf#}
52995325 {#header_close#}
53005326
53015327 {#header_open|@bytesToSlice#}
......@@ -5364,17 +5390,7 @@ comptime {
53645390 </p>
53655391 {#see_also|Import from C Header File|@cImport|@cDefine|@cUndef#}
53665392 {#header_close#}
5367 {#header_open|@cUndef#}
5368 <pre>{#syntax#}@cUndef(comptime name: []u8){#endsyntax#}</pre>
5369 <p>
5370 This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
5371 </p>
5372 <p>
5373 This appends <code>#undef $name</code> to the {#syntax#}@cImport{#endsyntax#}
5374 temporary buffer.
5375 </p>
5376 {#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#}
5377 {#header_close#}
5393
53785394 {#header_open|@clz#}
53795395 <pre>{#syntax#}@clz(x: T) U{#endsyntax#}</pre>
53805396 <p>
......@@ -5390,6 +5406,7 @@ comptime {
53905406 </p>
53915407 {#see_also|@ctz|@popCount#}
53925408 {#header_close#}
5409
53935410 {#header_open|@cmpxchgStrong#}
53945411 <pre>{#syntax#}@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T{#endsyntax#}</pre>
53955412 <p>
......@@ -5445,6 +5462,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
54455462 <p>{#syntax#}@typeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
54465463 {#see_also|Compile Variables|cmpxchgStrong#}
54475464 {#header_close#}
5465
54485466 {#header_open|@compileError#}
54495467 <pre>{#syntax#}@compileError(comptime msg: []u8){#endsyntax#}</pre>
54505468 <p>
......@@ -5457,6 +5475,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
54575475 and {#syntax#}comptime{#endsyntax#} functions.
54585476 </p>
54595477 {#header_close#}
5478
54605479 {#header_open|@compileLog#}
54615480 <pre>{#syntax#}@compileLog(args: ...){#endsyntax#}</pre>
54625481 <p>
......@@ -5511,6 +5530,7 @@ test "main" {
55115530}
55125531 {#code_end#}
55135532 {#header_close#}
5533
55145534 {#header_open|@ctz#}
55155535 <pre>{#syntax#}@ctz(x: T) U{#endsyntax#}</pre>
55165536 <p>
......@@ -5526,6 +5546,19 @@ test "main" {
55265546 </p>
55275547 {#see_also|@clz|@popCount#}
55285548 {#header_close#}
5549
5550 {#header_open|@cUndef#}
5551 <pre>{#syntax#}@cUndef(comptime name: []u8){#endsyntax#}</pre>
5552 <p>
5553 This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
5554 </p>
5555 <p>
5556 This appends <code>#undef $name</code> to the {#syntax#}@cImport{#endsyntax#}
5557 temporary buffer.
5558 </p>
5559 {#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#}
5560 {#header_close#}
5561
55295562 {#header_open|@divExact#}
55305563 <pre>{#syntax#}@divExact(numerator: T, denominator: T) T{#endsyntax#}</pre>
55315564 <p>
......@@ -5592,27 +5625,15 @@ test "main" {
55925625 {#see_also|@intToEnum#}
55935626 {#header_close#}
55945627
5595 {#header_open|@errSetCast#}
5596 <pre>{#syntax#}@errSetCast(comptime T: DestType, value: var) DestType{#endsyntax#}</pre>
5597 <p>
5598 Converts an error value from one error set to another error set. Attempting to convert an error
5599 which is not in the destination error set results in safety-protected {#link|Undefined Behavior#}.
5600 </p>
5601 {#header_close#}
5602
56035628 {#header_open|@errorName#}
5604 <pre>{#syntax#}@errorName(err: error) []u8{#endsyntax#}</pre>
5629 <pre>{#syntax#}@errorName(err: anyerror) []const u8{#endsyntax#}</pre>
56055630 <p>
5606 This function returns the string representation of an error. If an error
5607 declaration is:
5608 </p>
5609 <pre>{#syntax#}error OutOfMem{#endsyntax#}</pre>
5610 <p>
5611 Then the string representation is {#syntax#}"OutOfMem"{#endsyntax#}.
5631 This function returns the string representation of an error. The string representation
5632 of {#syntax#}error.OutOfMem{#endsyntax#} is {#syntax#}"OutOfMem"{#endsyntax#}.
56125633 </p>
56135634 <p>
56145635 If there are no calls to {#syntax#}@errorName{#endsyntax#} in an entire application,
5615 or all calls have a compile-time known value for {#syntax#}err{#endsyntax#}, then no
5636 or all calls have a compile-time known value for {#syntax#}err{#endsyntax#}, then no
56165637 error name table will be generated.
56175638 </p>
56185639 {#header_close#}
......@@ -5627,13 +5648,14 @@ test "main" {
56275648 {#header_close#}
56285649
56295650 {#header_open|@errorToInt#}
5630 <pre>{#syntax#}@errorToInt(err: var) @IntType(false, @sizeOf(error) * 8){#endsyntax#}</pre>
5651 <pre>{#syntax#}@errorToInt(err: var) @IntType(false, @sizeOf(anyerror) * 8){#endsyntax#}</pre>
56315652 <p>
56325653 Supports the following types:
56335654 </p>
56345655 <ul>
5635 <li>error unions</li>
5636 <li>{#syntax#}E!void{#endsyntax#}</li>
5656 <li>{#link|The Global Error Set#}</li>
5657 <li>{#link|Error Set Type#}</li>
5658 <li>{#link|Error Union Type#}</li>
56375659 </ul>
56385660 <p>
56395661 Converts an error to the integer representation of an error.
......@@ -5645,6 +5667,14 @@ test "main" {
56455667 {#see_also|@intToError#}
56465668 {#header_close#}
56475669
5670 {#header_open|@errSetCast#}
5671 <pre>{#syntax#}@errSetCast(comptime T: DestType, value: var) DestType{#endsyntax#}</pre>
5672 <p>
5673 Converts an error value from one error set to another error set. Attempting to convert an error
5674 which is not in the destination error set results in safety-protected {#link|Undefined Behavior#}.
5675 </p>
5676 {#header_close#}
5677
56485678 {#header_open|@export#}
56495679 <pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8{#endsyntax#}</pre>
56505680 <p>
......@@ -5713,6 +5743,7 @@ test "main" {
57135743 This function is only valid within function scope.
57145744 </p>
57155745 {#header_close#}
5746
57165747 {#header_open|@handle#}
57175748 <pre>{#syntax#}@handle(){#endsyntax#}</pre>
57185749 <p>
......@@ -5723,6 +5754,7 @@ test "main" {
57235754 This function is only valid within an async function scope.
57245755 </p>
57255756 {#header_close#}
5757
57265758 {#header_open|@import#}
57275759 <pre>{#syntax#}@import(comptime path: []u8) (namespace){#endsyntax#}</pre>
57285760 <p>
......@@ -5743,6 +5775,7 @@ test "main" {
57435775 </ul>
57445776 {#see_also|Compile Variables|@embedFile#}
57455777 {#header_close#}
5778
57465779 {#header_open|@inlineCall#}
57475780 <pre>{#syntax#}@inlineCall(function: X, args: ...) Y{#endsyntax#}</pre>
57485781 <p>
......@@ -5788,7 +5821,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
57885821 {#header_open|@intToError#}
57895822 <pre>{#syntax#}@intToError(value: @IntType(false, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>
57905823 <p>
5791 Converts from the integer representation of an error into the global error set type.
5824 Converts from the integer representation of an error into {#link|The Global Error Set#} type.
57925825 </p>
57935826 <p>
57945827 It is generally recommended to avoid this
......@@ -5822,6 +5855,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
58225855 bit count for an integer type is {#syntax#}65535{#endsyntax#}.
58235856 </p>
58245857 {#header_close#}
5858
58255859 {#header_open|@memberCount#}
58265860 <pre>{#syntax#}@memberCount(comptime T: type) comptime_int{#endsyntax#}</pre>
58275861 <p>
......@@ -5848,6 +5882,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
58485882 <pre>{#syntax#}@memberType(comptime T: type, comptime index: usize) type{#endsyntax#}</pre>
58495883 <p>Returns the field type of a struct or union.</p>
58505884 {#header_close#}
5885
58515886 {#header_open|@memcpy#}
58525887 <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}</pre>
58535888 <p>
......@@ -5866,6 +5901,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
58665901 <pre>{#syntax#}const mem = @import("std").mem;
58675902mem.copy(u8, dest[0...byte_count], source[0...byte_count]);{#endsyntax#}</pre>
58685903 {#header_close#}
5904
58695905 {#header_open|@memset#}
58705906 <pre>{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize){#endsyntax#}</pre>
58715907 <p>
......@@ -5883,6 +5919,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);{#endsyntax#}</pre>
58835919 <pre>{#syntax#}const mem = @import("std").mem;
58845920mem.set(u8, dest, c);{#endsyntax#}</pre>
58855921 {#header_close#}
5922
58865923 {#header_open|@mod#}
58875924 <pre>{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}</pre>
58885925 <p>
......@@ -5896,6 +5933,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
58965933 <p>For a function that returns an error code, see {#syntax#}@import("std").math.mod{#endsyntax#}.</p>
58975934 {#see_also|@rem#}
58985935 {#header_close#}
5936
58995937 {#header_open|@mulWithOverflow#}
59005938 <pre>{#syntax#}@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre>
59015939 <p>
......@@ -5904,6 +5942,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
59045942 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
59055943 </p>
59065944 {#header_close#}
5945
59075946 {#header_open|@newStackCall#}
59085947 <pre>{#syntax#}@newStackCall(new_stack: []u8, function: var, args: ...) var{#endsyntax#}</pre>
59095948 <p>
......@@ -5940,6 +5979,7 @@ fn targetFunction(x: i32) usize {
59405979}
59415980 {#code_end#}
59425981 {#header_close#}
5982
59435983 {#header_open|@noInlineCall#}
59445984 <pre>{#syntax#}@noInlineCall(function: var, args: ...) var{#endsyntax#}</pre>
59455985 <p>
......@@ -5962,6 +6002,7 @@ fn add(a: i32, b: i32) i32 {
59626002 </p>
59636003 {#see_also|@inlineCall#}
59646004 {#header_close#}
6005
59656006 {#header_open|@OpaqueType#}
59666007 <pre>{#syntax#}@OpaqueType() type{#endsyntax#}</pre>
59676008 <p>
......@@ -5985,6 +6026,7 @@ test "call foo" {
59856026}
59866027 {#code_end#}
59876028 {#header_close#}
6029
59886030 {#header_open|@panic#}
59896031 <pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre>
59906032 <p>
......@@ -6001,6 +6043,7 @@ test "call foo" {
60016043 </ul>
60026044 {#see_also|Root Source File#}
60036045 {#header_close#}
6046
60046047 {#header_open|@popCount#}
60056048 <pre>{#syntax#}@popCount(integer: var) var{#endsyntax#}</pre>
60066049 <p>Counts the number of bits set in an integer.</p>
......@@ -6011,12 +6054,14 @@ test "call foo" {
60116054 </p>
60126055 {#see_also|@ctz|@clz#}
60136056 {#header_close#}
6057
60146058 {#header_open|@ptrCast#}
60156059 <pre>{#syntax#}@ptrCast(comptime DestType: type, value: var) DestType{#endsyntax#}</pre>
60166060 <p>
60176061 Converts a pointer of one type to a pointer of another type.
60186062 </p>
60196063 {#header_close#}
6064
60206065 {#header_open|@ptrToInt#}
60216066 <pre>{#syntax#}@ptrToInt(value: var) usize{#endsyntax#}</pre>
60226067 <p>
......@@ -6031,6 +6076,7 @@ test "call foo" {
60316076 <p>To convert the other way, use {#link|@intToPtr#}</p>
60326077
60336078 {#header_close#}
6079
60346080 {#header_open|@rem#}
60356081 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
60366082 <p>
......@@ -6044,6 +6090,7 @@ test "call foo" {
60446090 <p>For a function that returns an error code, see {#syntax#}@import("std").math.rem{#endsyntax#}.</p>
60456091 {#see_also|@mod#}
60466092 {#header_close#}
6093
60476094 {#header_open|@returnAddress#}
60486095 <pre>{#syntax#}@returnAddress(){#endsyntax#}</pre>
60496096 <p>
......@@ -6064,19 +6111,14 @@ test "call foo" {
60646111 Ensures that a function will have a stack alignment of at least {#syntax#}alignment{#endsyntax#} bytes.
60656112 </p>
60666113 {#header_close#}
6114
60676115 {#header_open|@setCold#}
60686116 <pre>{#syntax#}@setCold(is_cold: bool){#endsyntax#}</pre>
60696117 <p>
60706118 Tells the optimizer that a function is rarely called.
60716119 </p>
60726120 {#header_close#}
6073 {#header_open|@setRuntimeSafety#}
6074 <pre>{#syntax#}@setRuntimeSafety(safety_on: bool){#endsyntax#}</pre>
6075 <p>
6076 Sets whether runtime safety checks are on for the scope that contains the function call.
6077 </p>
60786121
6079 {#header_close#}
60806122 {#header_open|@setEvalBranchQuota#}
60816123 <pre>{#syntax#}@setEvalBranchQuota(new_quota: usize){#endsyntax#}</pre>
60826124 <p>
......@@ -6111,6 +6153,7 @@ test "foo" {
61116153
61126154 {#see_also|comptime#}
61136155 {#header_close#}
6156
61146157 {#header_open|@setFloatMode#}
61156158 <pre>{#syntax#}@setFloatMode(mode: @import("builtin").FloatMode){#endsyntax#}</pre>
61166159 <p>
......@@ -6145,6 +6188,7 @@ pub const FloatMode = enum {
61456188 </p>
61466189 {#see_also|Floating Point Operations#}
61476190 {#header_close#}
6191
61486192 {#header_open|@setGlobalLinkage#}
61496193 <pre>{#syntax#}@setGlobalLinkage(global_variable_name, comptime linkage: GlobalLinkage){#endsyntax#}</pre>
61506194 <p>
......@@ -6152,6 +6196,15 @@ pub const FloatMode = enum {
61526196 </p>
61536197 {#see_also|Compile Variables#}
61546198 {#header_close#}
6199
6200 {#header_open|@setRuntimeSafety#}
6201 <pre>{#syntax#}@setRuntimeSafety(safety_on: bool){#endsyntax#}</pre>
6202 <p>
6203 Sets whether runtime safety checks are on for the scope that contains the function call.
6204 </p>
6205
6206 {#header_close#}
6207
61556208 {#header_open|@shlExact#}
61566209 <pre>{#syntax#}@shlExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre>
61576210 <p>
......@@ -6164,6 +6217,7 @@ pub const FloatMode = enum {
61646217 </p>
61656218 {#see_also|@shrExact|@shlWithOverflow#}
61666219 {#header_close#}
6220
61676221 {#header_open|@shlWithOverflow#}
61686222 <pre>{#syntax#}@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool{#endsyntax#}</pre>
61696223 <p>
......@@ -6177,6 +6231,7 @@ pub const FloatMode = enum {
61776231 </p>
61786232 {#see_also|@shlExact|@shrExact#}
61796233 {#header_close#}
6234
61806235 {#header_open|@shrExact#}
61816236 <pre>{#syntax#}@shrExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre>
61826237 <p>
......@@ -6218,6 +6273,7 @@ pub const FloatMode = enum {
62186273 This is a low-level intrinsic. Most code can use {#syntax#}std.math.sqrt{#endsyntax#} instead.
62196274 </p>
62206275 {#header_close#}
6276
62216277 {#header_open|@subWithOverflow#}
62226278 <pre>{#syntax#}@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre>
62236279 <p>
......@@ -6226,12 +6282,14 @@ pub const FloatMode = enum {
62266282 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
62276283 </p>
62286284 {#header_close#}
6285
62296286 {#header_open|@tagName#}
62306287 <pre>{#syntax#}@tagName(value: var) []const u8{#endsyntax#}</pre>
62316288 <p>
62326289 Converts an enum value or union value to a slice of bytes representing the name.
62336290 </p>
62346291 {#header_close#}
6292
62356293 {#header_open|@TagType#}
62366294 <pre>{#syntax#}@TagType(T: type) type{#endsyntax#}</pre>
62376295 <p>
......@@ -6241,6 +6299,7 @@ pub const FloatMode = enum {
62416299 For a union, returns the enum type that is used to store the tag value.
62426300 </p>
62436301 {#header_close#}
6302
62446303 {#header_open|@This#}
62456304 <pre>{#syntax#}@This() type{#endsyntax#}</pre>
62466305 <p>
......@@ -6276,6 +6335,7 @@ fn List(comptime T: type) type {
62766335 <a href="https://github.com/ziglang/zig/issues/1047">#1047</a> for details.
62776336 </p>
62786337 {#header_close#}
6338
62796339 {#header_open|@truncate#}
62806340 <pre>{#syntax#}@truncate(comptime T: type, integer) T{#endsyntax#}</pre>
62816341 <p>
......@@ -6300,6 +6360,7 @@ const b: u8 = @truncate(u8, a);
63006360 </p>
63016361
63026362 {#header_close#}
6363
63036364 {#header_open|@typeId#}
63046365 <pre>{#syntax#}@typeId(comptime T: type) @import("builtin").TypeId{#endsyntax#}</pre>
63056366 <p>
......@@ -6334,6 +6395,7 @@ pub const TypeId = enum {
63346395};
63356396 {#code_end#}
63366397 {#header_close#}
6398
63376399 {#header_open|@typeInfo#}
63386400 <pre>{#syntax#}@typeInfo(comptime T: type) @import("builtin").TypeInfo{#endsyntax#}</pre>
63396401 <p>
......@@ -6516,6 +6578,7 @@ pub const TypeInfo = union(TypeId) {
65166578};
65176579 {#code_end#}
65186580 {#header_close#}
6581
65196582 {#header_open|@typeName#}
65206583 <pre>{#syntax#}@typeName(T: type) []u8{#endsyntax#}</pre>
65216584 <p>
......@@ -6523,6 +6586,7 @@ pub const TypeInfo = union(TypeId) {
65236586 </p>
65246587
65256588 {#header_close#}
6589
65266590 {#header_open|@typeOf#}
65276591 <pre>{#syntax#}@typeOf(expression) type{#endsyntax#}</pre>
65286592 <p>
......@@ -6532,6 +6596,7 @@ pub const TypeInfo = union(TypeId) {
65326596
65336597 {#header_close#}
65346598 {#header_close#}
6599
65356600 {#header_open|Build Mode#}
65366601 <p>
65376602 Zig has four build modes:
......@@ -6659,7 +6724,7 @@ fn foo(x: []const u8) u8 {
66596724 {#header_close#}
66606725 {#header_open|Cast Negative Number to Unsigned Integer#}
66616726 <p>At compile-time:</p>
6662 {#code_begin|test_err|attempt to cast negative value to unsigned integer#}
6727 {#code_begin|test_err|cannot cast negative value -1 to unsigned integer type 'u32'#}
66636728comptime {
66646729 const value: i32 = -1;
66656730 const unsigned = @intCast(u32, value);
......@@ -6681,7 +6746,7 @@ pub fn main() void {
66816746 {#header_close#}
66826747 {#header_open|Cast Truncates Data#}
66836748 <p>At compile-time:</p>
6684 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#}
6749 {#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#}
66856750comptime {
66866751 const spartan_count: u16 = 300;
66876752 const byte = @intCast(u8, spartan_count);
......@@ -7830,11 +7895,11 @@ TypeExpr &lt;- PrefixTypeOp* ErrorUnionExpr
78307895ErrorUnionExpr &lt;- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
78317896
78327897SuffixExpr
7833 &lt;- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
7834 / PrimaryTypeExpr (SuffixOp / FnCallArgumnets)*
7898 &lt;- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments
7899 / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
78357900
78367901PrimaryTypeExpr
7837 &lt;- BUILTININDENTIFIER FnCallArgumnets
7902 &lt;- BUILTINIDENTIFIER FnCallArguments
78387903 / CHAR_LITERAL
78397904 / ContainerDecl
78407905 / ErrorSetDecl
......@@ -7884,11 +7949,11 @@ AsmOutput &lt;- COLON AsmOutputList AsmInput?
78847949
78857950AsmOutputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
78867951
7887AsmInput &lt;- COLON AsmInputList AsmCloppers?
7952AsmInput &lt;- COLON AsmInputList AsmClobbers?
78887953
78897954AsmInputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
78907955
7891AsmCloppers &lt;- COLON StringList
7956AsmClobbers &lt;- COLON StringList
78927957
78937958# *** Helper grammar ***
78947959BreakLabel &lt;- COLON IDENTIFIER
......@@ -8013,7 +8078,7 @@ SuffixOp
80138078
80148079AsyncPrefix &lt;- KEYWORD_async (LARROW PrefixExpr RARROW)?
80158080
8016FnCallArgumnets &lt;- LPAREN ExprList RPAREN
8081FnCallArguments &lt;- LPAREN ExprList RPAREN
80178082
80188083# Ptr specific
80198084ArrayTypeStart &lt;- LBRACKET Expr? RBRACKET
......@@ -8090,7 +8155,7 @@ STRINGLITERAL
80908155IDENTIFIER
80918156 &lt;- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
80928157 / "@\"" string_char* "\"" skip
8093BUILTININDENTIFIER &lt;- "@"[A-Za-z_][A-Za-z0-9_]* skip
8158BUILTINIDENTIFIER &lt;- "@"[A-Za-z_][A-Za-z0-9_]* skip
80948159
80958160
80968161AMPERSAND &lt;- '&' ![=] skip
......@@ -8109,9 +8174,9 @@ DOT2 &lt;- '..' ![.] skip
81098174DOT3 &lt;- '...' skip
81108175DOTASTERISK &lt;- '.*' skip
81118176DOTQUESTIONMARK &lt;- '.?' skip
8112EQUAL &lt;- '=' ![>=] skip
8177EQUAL &lt;- '=' ![&gt;=] skip
81138178EQUALEQUAL &lt;- '==' skip
8114EQUALRARROW &lt;- '=>' skip
8179EQUALRARROW &lt;- '=&gt;' skip
81158180EXCLAMATIONMARK &lt;- '!' ![=] skip
81168181EXCLAMATIONMARKEQUAL &lt;- '!=' skip
81178182LARROW &lt;- '&lt;' ![&lt;=] skip
......@@ -8121,11 +8186,11 @@ LARROWEQUAL &lt;- '&lt;=' skip
81218186LBRACE &lt;- '{' skip
81228187LBRACKET &lt;- '[' skip
81238188LPAREN &lt;- '(' skip
8124MINUS &lt;- '-' ![%=>] skip
8189MINUS &lt;- '-' ![%=&gt;] skip
81258190MINUSEQUAL &lt;- '-=' skip
81268191MINUSPERCENT &lt;- '-%' ![=] skip
81278192MINUSPERCENTEQUAL &lt;- '-%=' skip
8128MINUSRARROW &lt;- '->' skip
8193MINUSRARROW &lt;- '-&gt;' skip
81298194PERCENT &lt;- '%' ![=] skip
81308195PERCENTEQUAL &lt;- '%=' skip
81318196PIPE &lt;- '|' ![|=] skip
......@@ -8137,10 +8202,10 @@ PLUSEQUAL &lt;- '+=' skip
81378202PLUSPERCENT &lt;- '+%' ![=] skip
81388203PLUSPERCENTEQUAL &lt;- '+%=' skip
81398204QUESTIONMARK &lt;- '?' skip
8140RARROW &lt;- '>' ![>=] skip
8141RARROW2 &lt;- '>>' ![=] skip
8142RARROW2EQUAL &lt;- '>>=' skip
8143RARROWEQUAL &lt;- '>=' skip
8205RARROW &lt;- '&gt;' ![&gt;=] skip
8206RARROW2 &lt;- '&gt;&gt;' ![=] skip
8207RARROW2EQUAL &lt;- '&gt;&gt;=' skip
8208RARROWEQUAL &lt;- '&gt;=' skip
81448209RBRACE &lt;- '}' skip
81458210RBRACKET &lt;- ']' skip
81468211RPAREN &lt;- ')' skip
example/guess_number/main.zig+5-5
......@@ -15,7 +15,7 @@ pub fn main() !void {
1515 std.debug.warn("unable to seed random number generator: {}", err);
1616 return err;
1717 };
18 const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big);
18 const seed = std.mem.readIntNative(u64, &seed_bytes);
1919 var prng = std.rand.DefaultPrng.init(seed);
2020
2121 const answer = prng.random.range(u8, 0, 100) + 1;
......@@ -24,15 +24,15 @@ pub fn main() !void {
2424 try stdout.print("\nGuess a number between 1 and 100: ");
2525 var line_buf: [20]u8 = undefined;
2626
27 const line_len = io.readLine(line_buf[0..]) catch |err| switch (err) {
28 error.InputTooLong => {
27 const line = io.readLineSlice(line_buf[0..]) catch |err| switch (err) {
28 error.OutOfMemory => {
2929 try stdout.print("Input too long.\n");
3030 continue;
3131 },
32 error.EndOfFile, error.StdInUnavailable => return err,
32 else => return err,
3333 };
3434
35 const guess = fmt.parseUnsigned(u8, line_buf[0..line_len], 10) catch {
35 const guess = fmt.parseUnsigned(u8, line, 10) catch {
3636 try stdout.print("Invalid number.\n");
3737 continue;
3838 };
example/hello_world/hello.zig+1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn main() !void {
44 // If this program is run without stdout attached, exit with an error.
5 var stdout_file = try std.io.getStdOut();
5 const stdout_file = try std.io.getStdOut();
66 // If this program encounters pipe failure when printing to stdout, exit
77 // with an error.
88 try stdout_file.write("Hello, world!\n");
src-self-hosted/compilation.zig+2-1
......@@ -55,7 +55,7 @@ pub const ZigCompiler = struct {
5555
5656 var seed_bytes: [@sizeOf(u64)]u8 = undefined;
5757 try std.os.getRandomBytes(seed_bytes[0..]);
58 const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big);
58 const seed = mem.readIntNative(u64, &seed_bytes);
5959
6060 return ZigCompiler{
6161 .loop = loop,
......@@ -300,6 +300,7 @@ pub const Compilation = struct {
300300 UserResourceLimitReached,
301301 InvalidUtf8,
302302 BadPathName,
303 DeviceBusy,
303304 };
304305
305306 pub const Event = union(enum) {
src-self-hosted/libc_installation.zig+1-1
......@@ -172,7 +172,7 @@ pub const LibCInstallation = struct {
172172 try group.call(findNativeStaticLibDir, self, loop);
173173 try group.call(findNativeDynamicLinker, self, loop);
174174 },
175 builtin.Os.macosx => {
175 builtin.Os.macosx, builtin.Os.freebsd => {
176176 self.include_dir = try std.mem.dupe(loop.allocator, u8, "/usr/include");
177177 },
178178 else => @compileError("unimplemented: find libc for this OS"),
src-self-hosted/target.zig+155-151
......@@ -311,160 +311,164 @@ pub const Target = union(enum) {
311311 pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
312312 const env = self.getEnviron();
313313 const arch = self.getArch();
314 switch (env) {
315 builtin.Environ.android => {
316 if (self.is64bit()) {
317 return "/system/bin/linker64";
318 } else {
319 return "/system/bin/linker";
320 }
314 const os = self.getOs();
315 switch (os) {
316 builtin.Os.freebsd => {
317 return "/libexec/ld-elf.so.1";
321318 },
322 builtin.Environ.gnux32 => {
323 if (arch == builtin.Arch.x86_64) {
324 return "/libx32/ld-linux-x32.so.2";
319 builtin.Os.linux => {
320 switch (env) {
321 builtin.Environ.android => {
322 if (self.is64bit()) {
323 return "/system/bin/linker64";
324 } else {
325 return "/system/bin/linker";
326 }
327 },
328 builtin.Environ.gnux32 => {
329 if (arch == builtin.Arch.x86_64) {
330 return "/libx32/ld-linux-x32.so.2";
331 }
332 },
333 builtin.Environ.musl,
334 builtin.Environ.musleabi,
335 builtin.Environ.musleabihf,
336 => {
337 if (arch == builtin.Arch.x86_64) {
338 return "/lib/ld-musl-x86_64.so.1";
339 }
340 },
341 else => {},
325342 }
326 },
327 builtin.Environ.musl,
328 builtin.Environ.musleabi,
329 builtin.Environ.musleabihf,
330 => {
331 if (arch == builtin.Arch.x86_64) {
332 return "/lib/ld-musl-x86_64.so.1";
343 switch (arch) {
344 builtin.Arch.i386,
345 builtin.Arch.sparc,
346 builtin.Arch.sparcel,
347 => return "/lib/ld-linux.so.2",
348
349 builtin.Arch.aarch64v8_5a,
350 builtin.Arch.aarch64v8_4a,
351 builtin.Arch.aarch64v8_3a,
352 builtin.Arch.aarch64v8_2a,
353 builtin.Arch.aarch64v8_1a,
354 builtin.Arch.aarch64v8,
355 builtin.Arch.aarch64v8r,
356 builtin.Arch.aarch64v8m_baseline,
357 builtin.Arch.aarch64v8m_mainline,
358 => return "/lib/ld-linux-aarch64.so.1",
359
360 builtin.Arch.aarch64_bev8_5a,
361 builtin.Arch.aarch64_bev8_4a,
362 builtin.Arch.aarch64_bev8_3a,
363 builtin.Arch.aarch64_bev8_2a,
364 builtin.Arch.aarch64_bev8_1a,
365 builtin.Arch.aarch64_bev8,
366 builtin.Arch.aarch64_bev8r,
367 builtin.Arch.aarch64_bev8m_baseline,
368 builtin.Arch.aarch64_bev8m_mainline,
369 => return "/lib/ld-linux-aarch64_be.so.1",
370
371 builtin.Arch.armv8_5a,
372 builtin.Arch.armv8_4a,
373 builtin.Arch.armv8_3a,
374 builtin.Arch.armv8_2a,
375 builtin.Arch.armv8_1a,
376 builtin.Arch.armv8,
377 builtin.Arch.armv8r,
378 builtin.Arch.armv8m_baseline,
379 builtin.Arch.armv8m_mainline,
380 builtin.Arch.armv7,
381 builtin.Arch.armv7em,
382 builtin.Arch.armv7m,
383 builtin.Arch.armv7s,
384 builtin.Arch.armv7k,
385 builtin.Arch.armv7ve,
386 builtin.Arch.armv6,
387 builtin.Arch.armv6m,
388 builtin.Arch.armv6k,
389 builtin.Arch.armv6t2,
390 builtin.Arch.armv5,
391 builtin.Arch.armv5te,
392 builtin.Arch.armv4t,
393 builtin.Arch.thumb,
394 builtin.Arch.armebv8_5a,
395 builtin.Arch.armebv8_4a,
396 builtin.Arch.armebv8_3a,
397 builtin.Arch.armebv8_2a,
398 builtin.Arch.armebv8_1a,
399 builtin.Arch.armebv8,
400 builtin.Arch.armebv8r,
401 builtin.Arch.armebv8m_baseline,
402 builtin.Arch.armebv8m_mainline,
403 builtin.Arch.armebv7,
404 builtin.Arch.armebv7em,
405 builtin.Arch.armebv7m,
406 builtin.Arch.armebv7s,
407 builtin.Arch.armebv7k,
408 builtin.Arch.armebv7ve,
409 builtin.Arch.armebv6,
410 builtin.Arch.armebv6m,
411 builtin.Arch.armebv6k,
412 builtin.Arch.armebv6t2,
413 builtin.Arch.armebv5,
414 builtin.Arch.armebv5te,
415 builtin.Arch.armebv4t,
416 builtin.Arch.thumbeb,
417 => return switch (self.getFloatAbi()) {
418 FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
419 else => return "/lib/ld-linux.so.3",
420 },
421
422 builtin.Arch.mipsr6,
423 builtin.Arch.mipselr6,
424 builtin.Arch.mips64r6,
425 builtin.Arch.mips64elr6,
426 => return null,
427
428 builtin.Arch.powerpc => return "/lib/ld.so.1",
429 builtin.Arch.powerpc64 => return "/lib64/ld64.so.2",
430 builtin.Arch.powerpc64le => return "/lib64/ld64.so.2",
431 builtin.Arch.s390x => return "/lib64/ld64.so.1",
432 builtin.Arch.sparcv9 => return "/lib64/ld-linux.so.2",
433 builtin.Arch.x86_64 => return "/lib64/ld-linux-x86-64.so.2",
434
435 builtin.Arch.arc,
436 builtin.Arch.avr,
437 builtin.Arch.bpfel,
438 builtin.Arch.bpfeb,
439 builtin.Arch.hexagon,
440 builtin.Arch.msp430,
441 builtin.Arch.nios2,
442 builtin.Arch.r600,
443 builtin.Arch.amdgcn,
444 builtin.Arch.riscv32,
445 builtin.Arch.riscv64,
446 builtin.Arch.tce,
447 builtin.Arch.tcele,
448 builtin.Arch.xcore,
449 builtin.Arch.nvptx,
450 builtin.Arch.nvptx64,
451 builtin.Arch.le32,
452 builtin.Arch.le64,
453 builtin.Arch.amdil,
454 builtin.Arch.amdil64,
455 builtin.Arch.hsail,
456 builtin.Arch.hsail64,
457 builtin.Arch.spir,
458 builtin.Arch.spir64,
459 builtin.Arch.kalimbav3,
460 builtin.Arch.kalimbav4,
461 builtin.Arch.kalimbav5,
462 builtin.Arch.shave,
463 builtin.Arch.lanai,
464 builtin.Arch.wasm32,
465 builtin.Arch.wasm64,
466 builtin.Arch.renderscript32,
467 builtin.Arch.renderscript64,
468 => return null,
333469 }
334470 },
335 else => {},
336 }
337 switch (arch) {
338 builtin.Arch.i386,
339 builtin.Arch.sparc,
340 builtin.Arch.sparcel,
341 => return "/lib/ld-linux.so.2",
342
343 builtin.Arch.aarch64v8_5a,
344 builtin.Arch.aarch64v8_4a,
345 builtin.Arch.aarch64v8_3a,
346 builtin.Arch.aarch64v8_2a,
347 builtin.Arch.aarch64v8_1a,
348 builtin.Arch.aarch64v8,
349 builtin.Arch.aarch64v8r,
350 builtin.Arch.aarch64v8m_baseline,
351 builtin.Arch.aarch64v8m_mainline,
352 => return "/lib/ld-linux-aarch64.so.1",
353
354 builtin.Arch.aarch64_bev8_5a,
355 builtin.Arch.aarch64_bev8_4a,
356 builtin.Arch.aarch64_bev8_3a,
357 builtin.Arch.aarch64_bev8_2a,
358 builtin.Arch.aarch64_bev8_1a,
359 builtin.Arch.aarch64_bev8,
360 builtin.Arch.aarch64_bev8r,
361 builtin.Arch.aarch64_bev8m_baseline,
362 builtin.Arch.aarch64_bev8m_mainline,
363 => return "/lib/ld-linux-aarch64_be.so.1",
364
365 builtin.Arch.armv8_5a,
366 builtin.Arch.armv8_4a,
367 builtin.Arch.armv8_3a,
368 builtin.Arch.armv8_2a,
369 builtin.Arch.armv8_1a,
370 builtin.Arch.armv8,
371 builtin.Arch.armv8r,
372 builtin.Arch.armv8m_baseline,
373 builtin.Arch.armv8m_mainline,
374 builtin.Arch.armv7,
375 builtin.Arch.armv7em,
376 builtin.Arch.armv7m,
377 builtin.Arch.armv7s,
378 builtin.Arch.armv7k,
379 builtin.Arch.armv7ve,
380 builtin.Arch.armv6,
381 builtin.Arch.armv6m,
382 builtin.Arch.armv6k,
383 builtin.Arch.armv6t2,
384 builtin.Arch.armv5,
385 builtin.Arch.armv5te,
386 builtin.Arch.armv4t,
387 builtin.Arch.thumb,
388 => return switch (self.getFloatAbi()) {
389 FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
390 else => return "/lib/ld-linux.so.3",
391 },
392
393 builtin.Arch.armebv8_5a,
394 builtin.Arch.armebv8_4a,
395 builtin.Arch.armebv8_3a,
396 builtin.Arch.armebv8_2a,
397 builtin.Arch.armebv8_1a,
398 builtin.Arch.armebv8,
399 builtin.Arch.armebv8r,
400 builtin.Arch.armebv8m_baseline,
401 builtin.Arch.armebv8m_mainline,
402 builtin.Arch.armebv7,
403 builtin.Arch.armebv7em,
404 builtin.Arch.armebv7m,
405 builtin.Arch.armebv7s,
406 builtin.Arch.armebv7k,
407 builtin.Arch.armebv7ve,
408 builtin.Arch.armebv6,
409 builtin.Arch.armebv6m,
410 builtin.Arch.armebv6k,
411 builtin.Arch.armebv6t2,
412 builtin.Arch.armebv5,
413 builtin.Arch.armebv5te,
414 builtin.Arch.armebv4t,
415 builtin.Arch.thumbeb,
416 => return switch (self.getFloatAbi()) {
417 FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
418 else => return "/lib/ld-linux.so.3",
419 },
420
421 builtin.Arch.mipsr6,
422 builtin.Arch.mipselr6,
423 builtin.Arch.mips64r6,
424 builtin.Arch.mips64elr6,
425 => return null,
426
427 builtin.Arch.powerpc => return "/lib/ld.so.1",
428 builtin.Arch.powerpc64 => return "/lib64/ld64.so.2",
429 builtin.Arch.powerpc64le => return "/lib64/ld64.so.2",
430 builtin.Arch.s390x => return "/lib64/ld64.so.1",
431 builtin.Arch.sparcv9 => return "/lib64/ld-linux.so.2",
432 builtin.Arch.x86_64 => return "/lib64/ld-linux-x86-64.so.2",
433
434 builtin.Arch.arc,
435 builtin.Arch.avr,
436 builtin.Arch.bpfel,
437 builtin.Arch.bpfeb,
438 builtin.Arch.hexagon,
439 builtin.Arch.msp430,
440 builtin.Arch.nios2,
441 builtin.Arch.r600,
442 builtin.Arch.amdgcn,
443 builtin.Arch.riscv32,
444 builtin.Arch.riscv64,
445 builtin.Arch.tce,
446 builtin.Arch.tcele,
447 builtin.Arch.xcore,
448 builtin.Arch.nvptx,
449 builtin.Arch.nvptx64,
450 builtin.Arch.le32,
451 builtin.Arch.le64,
452 builtin.Arch.amdil,
453 builtin.Arch.amdil64,
454 builtin.Arch.hsail,
455 builtin.Arch.hsail64,
456 builtin.Arch.spir,
457 builtin.Arch.spir64,
458 builtin.Arch.kalimbav3,
459 builtin.Arch.kalimbav4,
460 builtin.Arch.kalimbav5,
461 builtin.Arch.shave,
462 builtin.Arch.lanai,
463 builtin.Arch.wasm32,
464 builtin.Arch.wasm64,
465 builtin.Arch.renderscript32,
466 builtin.Arch.renderscript64,
467 => return null,
471 else => return null,
468472 }
469473 }
470474
......@@ -513,6 +517,7 @@ pub const Target = union(enum) {
513517
514518 builtin.Os.linux,
515519 builtin.Os.macosx,
520 builtin.Os.freebsd,
516521 builtin.Os.openbsd,
517522 builtin.Os.zen,
518523 => switch (id) {
......@@ -547,7 +552,6 @@ pub const Target = union(enum) {
547552 builtin.Os.ananas,
548553 builtin.Os.cloudabi,
549554 builtin.Os.dragonfly,
550 builtin.Os.freebsd,
551555 builtin.Os.fuchsia,
552556 builtin.Os.ios,
553557 builtin.Os.kfreebsd,
src/all_types.hpp+13-1
......@@ -605,7 +605,6 @@ enum CastOp {
605605 CastOpFloatToInt,
606606 CastOpBoolToInt,
607607 CastOpResizeSlice,
608 CastOpBytesToSlice,
609608 CastOpNumLitToConcrete,
610609 CastOpErrSet,
611610 CastOpBitCast,
......@@ -1415,6 +1414,7 @@ enum BuiltinFnId {
14151414 BuiltinFnIdErrorReturnTrace,
14161415 BuiltinFnIdAtomicRmw,
14171416 BuiltinFnIdAtomicLoad,
1417 BuiltinFnIdBswap,
14181418};
14191419
14201420struct BuiltinFnEntry {
......@@ -1487,6 +1487,7 @@ enum ZigLLVMFnId {
14871487 ZigLLVMFnIdFloor,
14881488 ZigLLVMFnIdCeil,
14891489 ZigLLVMFnIdSqrt,
1490 ZigLLVMFnIdBswap,
14901491};
14911492
14921493enum AddSubMul {
......@@ -1516,6 +1517,9 @@ struct ZigLLVMFnKey {
15161517 uint32_t bit_count;
15171518 bool is_signed;
15181519 } overflow_arithmetic;
1520 struct {
1521 uint32_t bit_count;
1522 } bswap;
15191523 } data;
15201524};
15211525
......@@ -2158,6 +2162,7 @@ enum IrInstructionId {
21582162 IrInstructionIdMergeErrRetTraces,
21592163 IrInstructionIdMarkErrRetTracePtr,
21602164 IrInstructionIdSqrt,
2165 IrInstructionIdBswap,
21612166 IrInstructionIdErrSetCast,
21622167 IrInstructionIdToBytes,
21632168 IrInstructionIdFromBytes,
......@@ -3251,6 +3256,13 @@ struct IrInstructionCheckRuntimeScope {
32513256 IrInstruction *is_comptime;
32523257};
32533258
3259struct IrInstructionBswap {
3260 IrInstruction base;
3261
3262 IrInstruction *type;
3263 IrInstruction *op;
3264};
3265
32543266static const size_t slice_ptr_index = 0;
32553267static const size_t slice_len_index = 1;
32563268
src/analyze.cpp+97-61
......@@ -401,7 +401,8 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
401401}
402402
403403ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
404 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset_in_host, uint32_t host_int_bytes)
404 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
405 uint32_t bit_offset_in_host, uint32_t host_int_bytes)
405406{
406407 assert(!type_is_invalid(child_type));
407408 assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
......@@ -1059,7 +1060,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
10591060 }
10601061 zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481",
10611062 buf_ptr(&fn_type_id->return_type->name));
1062 } else if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb) {
1063 } else if (target_is_arm(&g->zig_target)) {
10631064 return type_size(g, fn_type_id->return_type) > 16;
10641065 }
10651066 zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481");
......@@ -1619,13 +1620,16 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
16191620 case ZigTypeIdUnion:
16201621 case ZigTypeIdFn:
16211622 case ZigTypeIdPromise:
1622 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
1623 return g->builtin_types.entry_invalid;
1624 if (type_requires_comptime(type_entry)) {
1625 add_node_error(g, param_node->data.param_decl.type,
1626 buf_sprintf("parameter of type '%s' must be declared comptime",
1627 buf_ptr(&type_entry->name)));
1628 return g->builtin_types.entry_invalid;
1623 switch (type_requires_comptime(g, type_entry)) {
1624 case ReqCompTimeNo:
1625 break;
1626 case ReqCompTimeYes:
1627 add_node_error(g, param_node->data.param_decl.type,
1628 buf_sprintf("parameter of type '%s' must be declared comptime",
1629 buf_ptr(&type_entry->name)));
1630 return g->builtin_types.entry_invalid;
1631 case ReqCompTimeInvalid:
1632 return g->builtin_types.entry_invalid;
16291633 }
16301634 break;
16311635 }
......@@ -1711,10 +1715,13 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
17111715 case ZigTypeIdUnion:
17121716 case ZigTypeIdFn:
17131717 case ZigTypeIdPromise:
1714 if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusZeroBitsKnown)))
1715 return g->builtin_types.entry_invalid;
1716 if (type_requires_comptime(fn_type_id.return_type)) {
1717 return get_generic_fn_type(g, &fn_type_id);
1718 switch (type_requires_comptime(g, fn_type_id.return_type)) {
1719 case ReqCompTimeInvalid:
1720 return g->builtin_types.entry_invalid;
1721 case ReqCompTimeYes:
1722 return get_generic_fn_type(g, &fn_type_id);
1723 case ReqCompTimeNo:
1724 break;
17181725 }
17191726 break;
17201727 }
......@@ -2560,8 +2567,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
25602567static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
25612568 assert(struct_type->id == ZigTypeIdStruct);
25622569
2563 Error err;
2564
25652570 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
25662571 return ErrorSemanticAnalyzeFail;
25672572 if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown)
......@@ -2619,13 +2624,15 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
26192624 buf_sprintf("enums, not structs, support field assignment"));
26202625 }
26212626
2622 if ((err = type_resolve(g, field_type, ResolveStatusZeroBitsKnown))) {
2623 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2624 continue;
2625 }
2626
2627 if (type_requires_comptime(field_type)) {
2628 struct_type->data.structure.requires_comptime = true;
2627 switch (type_requires_comptime(g, field_type)) {
2628 case ReqCompTimeYes:
2629 struct_type->data.structure.requires_comptime = true;
2630 break;
2631 case ReqCompTimeInvalid:
2632 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2633 continue;
2634 case ReqCompTimeNo:
2635 break;
26292636 }
26302637
26312638 if (!type_has_bits(field_type))
......@@ -2674,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
26742681 assert(decl_node->type == NodeTypeContainerDecl);
26752682 assert(struct_type->di_type);
26762683
2684 size_t field_count = struct_type->data.structure.src_field_count;
26772685 if (struct_type->data.structure.layout == ContainerLayoutPacked) {
26782686 struct_type->data.structure.abi_alignment = 1;
2679 }
2680
2681 size_t field_count = struct_type->data.structure.src_field_count;
2682 for (size_t i = 0; i < field_count; i += 1) {
2683 TypeStructField *field = &struct_type->data.structure.fields[i];
2684
2685 // If this assertion trips, look up the call stack. Probably something is
2686 // calling type_resolve with ResolveStatusAlignmentKnown when it should only
2687 // be resolving ResolveStatusZeroBitsKnown
2688 assert(field->type_entry != nullptr);
2689
2690 if (type_is_invalid(field->type_entry)) {
2691 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2692 break;
2687 for (size_t i = 0; i < field_count; i += 1) {
2688 TypeStructField *field = &struct_type->data.structure.fields[i];
2689 if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) {
2690 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2691 break;
2692 }
26932693 }
2694 } else for (size_t i = 0; i < field_count; i += 1) {
2695 TypeStructField *field = &struct_type->data.structure.fields[i];
2696 uint32_t this_field_align;
2697
2698 // TODO If we have no type_entry for the field, we've already failed to
2699 // compile the program correctly. This stage1 compiler needs a deeper
2700 // reworking to make this correct, or we can ignore the problem
2701 // and make sure it is fixed in stage2. This workaround is for when
2702 // there is a false positive of a dependency loop, of alignment depending
2703 // on itself. When this false positive happens we assume a pointer-aligned
2704 // field, which is usually fine but could be incorrectly over-aligned or
2705 // even under-aligned. See https://github.com/ziglang/zig/issues/1512
2706 if (field->type_entry == nullptr) {
2707 this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0));
2708 } else {
2709 if (type_is_invalid(field->type_entry)) {
2710 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2711 break;
2712 }
26942713
2695 if (!type_has_bits(field->type_entry))
2696 continue;
2714 if (!type_has_bits(field->type_entry))
2715 continue;
26972716
2698 // alignment of structs is the alignment of the most-aligned field
2699 if (struct_type->data.structure.layout != ContainerLayoutPacked) {
27002717 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
27012718 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
27022719 break;
27032720 }
27042721
2705 uint32_t this_field_align = get_abi_alignment(g, field->type_entry);
2722 this_field_align = get_abi_alignment(g, field->type_entry);
27062723 assert(this_field_align != 0);
2707 if (this_field_align > struct_type->data.structure.abi_alignment) {
2708 struct_type->data.structure.abi_alignment = this_field_align;
2709 }
2724 }
2725 // alignment of structs is the alignment of the most-aligned field
2726 if (this_field_align > struct_type->data.structure.abi_alignment) {
2727 struct_type->data.structure.abi_alignment = this_field_align;
27102728 }
27112729 }
27122730
......@@ -2890,11 +2908,17 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
28902908 }
28912909 union_field->type_entry = field_type;
28922910
2893 if (type_requires_comptime(field_type)) {
2894 union_type->data.unionation.requires_comptime = true;
2911 switch (type_requires_comptime(g, field_type)) {
2912 case ReqCompTimeInvalid:
2913 union_type->data.unionation.is_invalid = true;
2914 continue;
2915 case ReqCompTimeYes:
2916 union_type->data.unionation.requires_comptime = true;
2917 break;
2918 case ReqCompTimeNo:
2919 break;
28952920 }
28962921
2897
28982922 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
28992923 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
29002924 buf_sprintf("non-enum union field assignment"));
......@@ -4579,7 +4603,10 @@ void find_libc_include_path(CodeGen *g) {
45794603 fprintf(stderr, "Unable to determine libc include path. --libc-include-dir");
45804604 exit(1);
45814605 }
4582 } else if (g->zig_target.os == OsLinux || g->zig_target.os == OsMacOSX) {
4606 } else if (g->zig_target.os == OsLinux ||
4607 g->zig_target.os == OsMacOSX ||
4608 g->zig_target.os == OsFreeBSD)
4609 {
45834610 g->libc_include_dir = get_posix_libc_include_path();
45844611 } else {
45854612 fprintf(stderr, "Unable to determine libc include path.\n"
......@@ -4627,6 +4654,8 @@ void find_libc_lib_path(CodeGen *g) {
46274654
46284655 } else if (g->zig_target.os == OsLinux) {
46294656 g->libc_lib_dir = get_linux_libc_lib_path("crt1.o");
4657 } else if (g->zig_target.os == OsFreeBSD) {
4658 g->libc_lib_dir = buf_create_from_str("/usr/lib");
46304659 } else {
46314660 zig_panic("Unable to determine libc lib path.");
46324661 }
......@@ -4639,6 +4668,8 @@ void find_libc_lib_path(CodeGen *g) {
46394668 return;
46404669 } else if (g->zig_target.os == OsLinux) {
46414670 g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o");
4671 } else if (g->zig_target.os == OsFreeBSD) {
4672 g->libc_static_lib_dir = buf_create_from_str("/usr/lib");
46424673 } else {
46434674 zig_panic("Unable to determine libc static lib path.");
46444675 }
......@@ -5089,7 +5120,10 @@ bool type_has_bits(ZigType *type_entry) {
50895120 return !type_entry->zero_bits;
50905121}
50915122
5092bool type_requires_comptime(ZigType *type_entry) {
5123ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
5124 Error err;
5125 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5126 return ReqCompTimeInvalid;
50935127 switch (type_entry->id) {
50945128 case ZigTypeIdInvalid:
50955129 case ZigTypeIdOpaque:
......@@ -5102,27 +5136,25 @@ bool type_requires_comptime(ZigType *type_entry) {
51025136 case ZigTypeIdNamespace:
51035137 case ZigTypeIdBoundFn:
51045138 case ZigTypeIdArgTuple:
5105 return true;
5139 return ReqCompTimeYes;
51065140 case ZigTypeIdArray:
5107 return type_requires_comptime(type_entry->data.array.child_type);
5141 return type_requires_comptime(g, type_entry->data.array.child_type);
51085142 case ZigTypeIdStruct:
5109 assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
5110 return type_entry->data.structure.requires_comptime;
5143 return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
51115144 case ZigTypeIdUnion:
5112 assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
5113 return type_entry->data.unionation.requires_comptime;
5145 return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
51145146 case ZigTypeIdOptional:
5115 return type_requires_comptime(type_entry->data.maybe.child_type);
5147 return type_requires_comptime(g, type_entry->data.maybe.child_type);
51165148 case ZigTypeIdErrorUnion:
5117 return type_requires_comptime(type_entry->data.error_union.payload_type);
5149 return type_requires_comptime(g, type_entry->data.error_union.payload_type);
51185150 case ZigTypeIdPointer:
51195151 if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) {
5120 return false;
5152 return ReqCompTimeNo;
51215153 } else {
5122 return type_requires_comptime(type_entry->data.pointer.child_type);
5154 return type_requires_comptime(g, type_entry->data.pointer.child_type);
51235155 }
51245156 case ZigTypeIdFn:
5125 return type_entry->data.fn.is_generic;
5157 return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
51265158 case ZigTypeIdEnum:
51275159 case ZigTypeIdErrorSet:
51285160 case ZigTypeIdBool:
......@@ -5131,7 +5163,7 @@ bool type_requires_comptime(ZigType *type_entry) {
51315163 case ZigTypeIdVoid:
51325164 case ZigTypeIdUnreachable:
51335165 case ZigTypeIdPromise:
5134 return false;
5166 return ReqCompTimeNo;
51355167 }
51365168 zig_unreachable();
51375169}
......@@ -6090,6 +6122,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
60906122 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089;
60916123 case ZigLLVMFnIdSqrt:
60926124 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385;
6125 case ZigLLVMFnIdBswap:
6126 return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;
60936127 case ZigLLVMFnIdOverflowArithmetic:
60946128 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +
60956129 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +
......@@ -6108,6 +6142,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
61086142 return a.data.clz.bit_count == b.data.clz.bit_count;
61096143 case ZigLLVMFnIdPopCount:
61106144 return a.data.pop_count.bit_count == b.data.pop_count.bit_count;
6145 case ZigLLVMFnIdBswap:
6146 return a.data.bswap.bit_count == b.data.bswap.bit_count;
61116147 case ZigLLVMFnIdFloor:
61126148 case ZigLLVMFnIdCeil:
61136149 case ZigLLVMFnIdSqrt:
src/analyze.hpp+7-1
......@@ -87,7 +87,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
8787ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
8888void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
8989AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
90bool type_requires_comptime(ZigType *type_entry);
9190Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
9291Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
9392void complete_enum(CodeGen *g, ZigType *enum_type);
......@@ -216,4 +215,11 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);
216215
217216uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field);
218217
218enum ReqCompTime {
219 ReqCompTimeInvalid,
220 ReqCompTimeNo,
221 ReqCompTimeYes,
222};
223ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry);
224
219225#endif
src/buffer.hpp+10
......@@ -181,5 +181,15 @@ static inline Slice<uint8_t> buf_to_slice(Buf *buf) {
181181 return Slice<uint8_t>{reinterpret_cast<uint8_t*>(buf_ptr(buf)), buf_len(buf)};
182182}
183183
184static inline void buf_replace(Buf* buf, char from, char to) {
185 const size_t count = buf_len(buf);
186 char* ptr = buf_ptr(buf);
187 for (size_t i = 0; i < count; ++i) {
188 char& l = ptr[i];
189 if (l == from)
190 l = to;
191 }
192}
193
184194
185195#endif
src/cache_hash.cpp+4-2
......@@ -352,8 +352,9 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
352352 // if the mtime matches we can trust the digest
353353 OsFile this_file;
354354 if ((err = os_file_open_r(chf->path, &this_file))) {
355 fprintf(stderr, "Unable to open %s\n: %s", buf_ptr(chf->path), err_str(err));
355356 os_file_close(ch->manifest_file);
356 return err;
357 return ErrorCacheUnavailable;
357358 }
358359 OsTimeStamp actual_mtime;
359360 if ((err = os_file_mtime(this_file, &actual_mtime))) {
......@@ -392,8 +393,9 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
392393 for (; file_i < input_file_count; file_i += 1) {
393394 CacheHashFile *chf = &ch->files.at(file_i);
394395 if ((err = populate_file_hash(ch, chf, nullptr))) {
396 fprintf(stderr, "Unable to hash %s: %s\n", buf_ptr(chf->path), err_str(err));
395397 os_file_close(ch->manifest_file);
396 return err;
398 return ErrorCacheUnavailable;
397399 }
398400 }
399401 return ErrorNone;
src/codegen.cpp+77-34
......@@ -129,6 +129,11 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
129129 Buf *src_dir = buf_alloc();
130130 os_path_split(root_src_path, src_dir, src_basename);
131131
132 if (buf_len(src_basename) == 0) {
133 fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path));
134 exit(1);
135 }
136
132137 g->root_package = new_package(buf_ptr(src_dir), buf_ptr(src_basename));
133138 g->std_package = new_package(buf_ptr(g->zig_std_dir), "index.zig");
134139 g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
......@@ -1645,7 +1650,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
16451650 zig_unreachable();
16461651 }
16471652
1648 if (actual_bits >= wanted_bits && actual_type->id == ZigTypeIdInt &&
1653 if (actual_type->id == ZigTypeIdInt &&
16491654 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
16501655 want_runtime_safety)
16511656 {
......@@ -2877,32 +2882,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
28772882 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
28782883
28792884
2880 return cast_instruction->tmp_ptr;
2881 }
2882 case CastOpBytesToSlice:
2883 {
2884 assert(cast_instruction->tmp_ptr);
2885 assert(wanted_type->id == ZigTypeIdStruct);
2886 assert(wanted_type->data.structure.is_slice);
2887 assert(actual_type->id == ZigTypeIdArray);
2888
2889 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
2890 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
2891
2892
2893 size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index;
2894 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2895 (unsigned)wanted_ptr_index, "");
2896 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, "");
2897 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
2898
2899 size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
2900 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2901 (unsigned)wanted_len_index, "");
2902 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
2903 actual_type->data.array.len / type_size(g, wanted_child_type), false);
2904 gen_store_untyped(g, len_val, len_ptr, 0, false);
2905
29062885 return cast_instruction->tmp_ptr;
29072886 }
29082887 case CastOpIntToFloat:
......@@ -3660,6 +3639,13 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
36603639 AsmOutput *asm_output = asm_expr->output_list.at(i);
36613640 bool is_return = (asm_output->return_type != nullptr);
36623641 assert(*buf_ptr(asm_output->constraint) == '=');
3642 // LLVM uses commas internally to separate different constraints,
3643 // alternative constraints are achieved with pipes.
3644 // We still allow the user to use commas in a way that is similar
3645 // to GCC's inline assembly.
3646 // http://llvm.org/docs/LangRef.html#constraint-codes
3647 buf_replace(asm_output->constraint, ',', '|');
3648
36633649 if (is_return) {
36643650 buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1);
36653651 } else {
......@@ -3679,14 +3665,30 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
36793665 }
36803666 for (size_t i = 0; i < asm_expr->input_list.length; i += 1, total_index += 1, param_index += 1) {
36813667 AsmInput *asm_input = asm_expr->input_list.at(i);
3668 buf_replace(asm_input->constraint, ',', '|');
36823669 IrInstruction *ir_input = instruction->input_list[i];
36833670 buf_append_buf(&constraint_buf, asm_input->constraint);
36843671 if (total_index + 1 < total_constraint_count) {
36853672 buf_append_char(&constraint_buf, ',');
36863673 }
36873674
3688 param_types[param_index] = ir_input->value.type->type_ref;
3689 param_values[param_index] = ir_llvm_value(g, ir_input);
3675 ZigType *const type = ir_input->value.type;
3676 LLVMTypeRef type_ref = type->type_ref;
3677 LLVMValueRef value_ref = ir_llvm_value(g, ir_input);
3678 // Handle integers of non pot bitsize by widening them.
3679 if (type->id == ZigTypeIdInt) {
3680 const size_t bitsize = type->data.integral.bit_count;
3681 if (bitsize < 8 || !is_power_of_2(bitsize)) {
3682 const bool is_signed = type->data.integral.is_signed;
3683 const size_t wider_bitsize = bitsize < 8 ? 8 : round_to_next_power_of_2(bitsize);
3684 ZigType *const wider_type = get_int_type(g, is_signed, wider_bitsize);
3685 type_ref = wider_type->type_ref;
3686 value_ref = gen_widen_or_shorten(g, false, type, wider_type, value_ref);
3687 }
3688 }
3689
3690 param_types[param_index] = type_ref;
3691 param_values[param_index] = value_ref;
36903692 }
36913693 for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) {
36923694 Buf *clobber_buf = asm_expr->clobber_list.at(i);
......@@ -3705,8 +3707,8 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
37053707 LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, (unsigned)input_and_output_count, false);
37063708
37073709 bool is_volatile = asm_expr->is_volatile || (asm_expr->output_list.length == 0);
3708 LLVMValueRef asm_fn = LLVMConstInlineAsm(function_type, buf_ptr(&llvm_template),
3709 buf_ptr(&constraint_buf), is_volatile, false);
3710 LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template),
3711 buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT);
37103712
37113713 return LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, "");
37123714}
......@@ -3786,6 +3788,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
37863788 n_args = 1;
37873789 key.id = ZigLLVMFnIdPopCount;
37883790 key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count;
3791 } else if (fn_id == BuiltinFnIdBswap) {
3792 fn_name = "bswap";
3793 n_args = 1;
3794 key.id = ZigLLVMFnIdBswap;
3795 key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count;
37893796 } else {
37903797 zig_unreachable();
37913798 }
......@@ -5070,6 +5077,29 @@ static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstr
50705077 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
50715078}
50725079
5080static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) {
5081 LLVMValueRef op = ir_llvm_value(g, instruction->op);
5082 ZigType *int_type = instruction->base.value.type;
5083 assert(int_type->id == ZigTypeIdInt);
5084 if (int_type->data.integral.bit_count % 16 == 0) {
5085 LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value.type, BuiltinFnIdBswap);
5086 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
5087 }
5088 // Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate
5089 ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed,
5090 int_type->data.integral.bit_count + 8);
5091 // aabbcc
5092 LLVMValueRef extended = LLVMBuildZExt(g->builder, op, extended_type->type_ref, "");
5093 // 00aabbcc
5094 LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap);
5095 LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, "");
5096 // ccbbaa00
5097 LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped,
5098 LLVMConstInt(extended_type->type_ref, 8, false), "");
5099 // 00ccbbaa
5100 return LLVMBuildTrunc(g->builder, shifted, int_type->type_ref, "");
5101}
5102
50735103static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
50745104 AstNode *source_node = instruction->source_node;
50755105 Scope *scope = instruction->scope;
......@@ -5307,6 +5337,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
53075337 return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
53085338 case IrInstructionIdSqrt:
53095339 return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);
5340 case IrInstructionIdBswap:
5341 return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
53105342 }
53115343 zig_unreachable();
53125344}
......@@ -6258,8 +6290,14 @@ static void do_code_gen(CodeGen *g) {
62586290 }
62596291 if (ir_get_var_is_comptime(var))
62606292 continue;
6261 if (type_requires_comptime(var->value->type))
6262 continue;
6293 switch (type_requires_comptime(g, var->value->type)) {
6294 case ReqCompTimeInvalid:
6295 zig_unreachable();
6296 case ReqCompTimeYes:
6297 continue;
6298 case ReqCompTimeNo:
6299 break;
6300 }
62636301
62646302 if (var->src_arg_index == SIZE_MAX) {
62656303 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name), var->align_bytes);
......@@ -6723,6 +6761,7 @@ static void define_builtin_fns(CodeGen *g) {
67236761 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
67246762 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
67256763 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
6764 create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2);
67266765}
67276766
67286767static const char *bool_to_str(bool b) {
......@@ -8149,7 +8188,11 @@ void codegen_build_and_link(CodeGen *g) {
81498188 os_path_join(stage1_dir, buf_create_from_str("build"), manifest_dir);
81508189
81518190 if ((err = check_cache(g, manifest_dir, &digest))) {
8152 fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
8191 if (err == ErrorCacheUnavailable) {
8192 // message already printed
8193 } else {
8194 fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
8195 }
81538196 exit(1);
81548197 }
81558198
src/error.cpp+1
......@@ -33,6 +33,7 @@ const char *err_str(Error err) {
3333 case ErrorSharingViolation: return "sharing violation";
3434 case ErrorPipeBusy: return "pipe busy";
3535 case ErrorPrimitiveTypeNotFound: return "primitive type not found";
36 case ErrorCacheUnavailable: return "cache unavailable";
3637 }
3738 return "(invalid error)";
3839}
src/error.hpp+1
......@@ -35,6 +35,7 @@ enum Error {
3535 ErrorSharingViolation,
3636 ErrorPipeBusy,
3737 ErrorPrimitiveTypeNotFound,
38 ErrorCacheUnavailable,
3839};
3940
4041const char *err_str(Error err);
src/ir.cpp+601-206
......@@ -34,6 +34,7 @@ struct IrAnalyze {
3434 size_t old_bb_index;
3535 size_t instruction_index;
3636 ZigType *explicit_return_type;
37 AstNode *explicit_return_type_source_node;
3738 ZigList<IrInstruction *> src_implicit_return_type_list;
3839 IrBasicBlock *const_predecessor_bb;
3940};
......@@ -66,6 +67,8 @@ enum ConstCastResultId {
6667struct ConstCastOnly;
6768struct ConstCastArg {
6869 size_t arg_index;
70 ZigType *actual_param_type;
71 ZigType *expected_param_type;
6972 ConstCastOnly *child;
7073};
7174
......@@ -138,6 +141,11 @@ struct ConstCastErrSetMismatch {
138141 ZigList<ErrorTableEntry *> missing_errors;
139142};
140143
144enum UndefAllowed {
145 UndefOk,
146 UndefBad,
147};
148
141149static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
142150static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);
143151static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
......@@ -151,12 +159,14 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
151159static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
152160static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
153161static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
154static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
162static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val);
155163static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
156164static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
157165 ConstExprValue *out_val, ConstExprValue *ptr_val);
158166static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
159167 ZigType *dest_type, IrInstruction *dest_type_src);
168static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
169static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
160170
161171static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
162172 assert(get_src_ptr_type(const_val->type) != nullptr);
......@@ -847,6 +857,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) {
847857 return IrInstructionIdSqrt;
848858}
849859
860static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
861 return IrInstructionIdBswap;
862}
863
850864static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {
851865 return IrInstructionIdCheckRuntimeScope;
852866}
......@@ -2696,6 +2710,17 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc
26962710 return &instruction->base;
26972711}
26982712
2713static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
2714 IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node);
2715 instruction->type = type;
2716 instruction->op = op;
2717
2718 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
2719 ir_ref_instruction(op, irb->current_basic_block);
2720
2721 return &instruction->base;
2722}
2723
26992724static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
27002725 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
27012726 instruction->scope_is_comptime = scope_is_comptime;
......@@ -4680,6 +4705,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46804705 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
46814706 return ir_lval_wrap(irb, scope, result, lval);
46824707 }
4708 case BuiltinFnIdBswap:
4709 {
4710 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4711 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4712 if (arg0_value == irb->codegen->invalid_instruction)
4713 return arg0_value;
4714
4715 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4716 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4717 if (arg1_value == irb->codegen->invalid_instruction)
4718 return arg1_value;
4719
4720 IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);
4721 return ir_lval_wrap(irb, scope, result, lval);
4722 }
46834723 }
46844724 zig_unreachable();
46854725}
......@@ -5530,6 +5570,15 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
55305570 return irb->codegen->invalid_instruction;
55315571 }
55325572 }
5573
5574 const char modifier = *buf_ptr(asm_output->constraint);
5575 if (modifier != '=') {
5576 add_node_error(irb->codegen, node,
5577 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported."
5578 " Compiler TODO: see https://github.com/ziglang/zig/issues/215",
5579 buf_ptr(asm_output->asm_symbolic_name), modifier));
5580 return irb->codegen->invalid_instruction;
5581 }
55335582 }
55345583 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) {
55355584 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
......@@ -7316,15 +7365,31 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
73167365 return ir_add_error_node(ira, source_instruction->source_node, msg);
73177366}
73187367
7368// This function takes a comptime ptr and makes the child const value conform to the type
7369// described by the pointer.
7370static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, AstNode *source_node, ConstExprValue *ptr_val) {
7371 Error err;
7372 assert(ptr_val->type->id == ZigTypeIdPointer);
7373 ConstExprValue tmp = {};
7374 tmp.special = ConstValSpecialStatic;
7375 tmp.type = ptr_val->type->data.pointer.child_type;
7376 if ((err = ir_read_const_ptr(ira, source_node, &tmp, ptr_val)))
7377 return err;
7378 ConstExprValue *child_val = const_ptr_pointee_unchecked(ira->codegen, ptr_val);
7379 copy_const_val(child_val, &tmp, false);
7380 return ErrorNone;
7381}
7382
73197383static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) {
7384 Error err;
73207385 ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
73217386 assert(val != nullptr);
73227387 assert(const_val->type->id == ZigTypeIdPointer);
73237388 ZigType *expected_type = const_val->type->data.pointer.child_type;
73247389 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
7325 ir_add_error_node(ira, source_node,
7326 buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955"));
7327 return nullptr;
7390 if ((err = eval_comptime_ptr_reinterpret(ira, source_node, const_val)))
7391 return nullptr;
7392 return const_ptr_pointee_unchecked(ira->codegen, const_val);
73287393 }
73297394 return val;
73307395}
......@@ -8063,15 +8128,153 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
80638128 return false;
80648129 }
80658130
8066 ConstExprValue *const_val = &instruction->value;
8067 assert(const_val->special != ConstValSpecialRuntime);
8131 ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad);
8132 assert(const_val != nullptr);
8133
8134 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt);
8135 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat);
80688136
8069 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt ||
8070 const_val->type->id == ZigTypeIdComptimeInt);
8071 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat ||
8072 const_val->type->id == ZigTypeIdComptimeFloat);
80738137 if (other_type->id == ZigTypeIdFloat) {
8074 return true;
8138 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) {
8139 return true;
8140 }
8141 if (const_val->type->id == ZigTypeIdInt) {
8142 BigFloat tmp_bf;
8143 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint);
8144 BigFloat orig_bf;
8145 switch (other_type->data.floating.bit_count) {
8146 case 16: {
8147 float16_t tmp = bigfloat_to_f16(&tmp_bf);
8148 bigfloat_init_16(&orig_bf, tmp);
8149 break;
8150 }
8151 case 32: {
8152 float tmp = bigfloat_to_f32(&tmp_bf);
8153 bigfloat_init_32(&orig_bf, tmp);
8154 break;
8155 }
8156 case 64: {
8157 double tmp = bigfloat_to_f64(&tmp_bf);
8158 bigfloat_init_64(&orig_bf, tmp);
8159 break;
8160 }
8161 case 80:
8162 zig_panic("TODO");
8163 case 128: {
8164 float128_t tmp = bigfloat_to_f128(&tmp_bf);
8165 bigfloat_init_128(&orig_bf, tmp);
8166 break;
8167 }
8168 default:
8169 zig_unreachable();
8170 }
8171 BigInt orig_bi;
8172 bigint_init_bigfloat(&orig_bi, &orig_bf);
8173 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) {
8174 return true;
8175 }
8176 Buf *val_buf = buf_alloc();
8177 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10);
8178 ir_add_error(ira, instruction,
8179 buf_sprintf("integer value %s has no representation in type '%s'",
8180 buf_ptr(val_buf),
8181 buf_ptr(&other_type->name)));
8182 return false;
8183 }
8184 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) {
8185 return true;
8186 }
8187 switch (other_type->data.floating.bit_count) {
8188 case 16:
8189 switch (const_val->type->data.floating.bit_count) {
8190 case 32: {
8191 float16_t tmp = zig_double_to_f16(const_val->data.x_f32);
8192 float orig = zig_f16_to_double(tmp);
8193 if (const_val->data.x_f32 == orig) {
8194 return true;
8195 }
8196 break;
8197 }
8198 case 64: {
8199 float16_t tmp = zig_double_to_f16(const_val->data.x_f64);
8200 double orig = zig_f16_to_double(tmp);
8201 if (const_val->data.x_f64 == orig) {
8202 return true;
8203 }
8204 break;
8205 }
8206 case 80:
8207 zig_panic("TODO");
8208 case 128: {
8209 float16_t tmp = f128M_to_f16(&const_val->data.x_f128);
8210 float128_t orig;
8211 f16_to_f128M(tmp, &orig);
8212 if (f128M_eq(&orig, &const_val->data.x_f128)) {
8213 return true;
8214 }
8215 break;
8216 }
8217 default:
8218 zig_unreachable();
8219 }
8220 break;
8221 case 32:
8222 switch (const_val->type->data.floating.bit_count) {
8223 case 64: {
8224 float tmp = const_val->data.x_f64;
8225 double orig = tmp;
8226 if (const_val->data.x_f64 == orig) {
8227 return true;
8228 }
8229 break;
8230 }
8231 case 80:
8232 zig_panic("TODO");
8233 case 128: {
8234 float32_t tmp = f128M_to_f32(&const_val->data.x_f128);
8235 float128_t orig;
8236 f32_to_f128M(tmp, &orig);
8237 if (f128M_eq(&orig, &const_val->data.x_f128)) {
8238 return true;
8239 }
8240 break;
8241 }
8242 default:
8243 zig_unreachable();
8244 }
8245 break;
8246 case 64:
8247 switch (const_val->type->data.floating.bit_count) {
8248 case 80:
8249 zig_panic("TODO");
8250 case 128: {
8251 float64_t tmp = f128M_to_f64(&const_val->data.x_f128);
8252 float128_t orig;
8253 f64_to_f128M(tmp, &orig);
8254 if (f128M_eq(&orig, &const_val->data.x_f128)) {
8255 return true;
8256 }
8257 break;
8258 }
8259 default:
8260 zig_unreachable();
8261 }
8262 break;
8263 case 80:
8264 assert(const_val->type->data.floating.bit_count == 128);
8265 zig_panic("TODO");
8266 case 128:
8267 return true;
8268 default:
8269 zig_unreachable();
8270 }
8271 Buf *val_buf = buf_alloc();
8272 float_append_buf(val_buf, const_val);
8273 ir_add_error(ira, instruction,
8274 buf_sprintf("cast of value %s to type '%s' loses information",
8275 buf_ptr(val_buf),
8276 buf_ptr(&other_type->name)));
8277 return false;
80758278 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) {
80768279 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) {
80778280 Buf *val_buf = buf_alloc();
......@@ -8484,6 +8687,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
84848687 if (arg_child.id != ConstCastResultIdOk) {
84858688 result.id = ConstCastResultIdFnArg;
84868689 result.data.fn_arg.arg_index = i;
8690 result.data.fn_arg.actual_param_type = actual_param_info->type;
8691 result.data.fn_arg.expected_param_type = expected_param_info->type;
84878692 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1);
84888693 *result.data.fn_arg.child = arg_child;
84898694 return result;
......@@ -9134,7 +9339,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
91349339 const_val->type = new_type;
91359340 break;
91369341 case CastOpResizeSlice:
9137 case CastOpBytesToSlice:
91389342 // can't do it
91399343 zig_unreachable();
91409344 case CastOpIntToFloat:
......@@ -9191,7 +9395,7 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
91919395 ZigType *wanted_type, CastOp cast_op, bool need_alloca)
91929396{
91939397 if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) &&
9194 cast_op != CastOpResizeSlice && cast_op != CastOpBytesToSlice)
9398 cast_op != CastOpResizeSlice)
91959399 {
91969400 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
91979401 source_instr->source_node, wanted_type);
......@@ -9453,11 +9657,6 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
94539657 return const_instr;
94549658}
94559659
9456enum UndefAllowed {
9457 UndefOk,
9458 UndefBad,
9459};
9460
94619660static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) {
94629661 switch (value->value.special) {
94639662 case ConstValSpecialStatic:
......@@ -10014,7 +10213,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
1001410213 return ira->codegen->invalid_instruction;
1001510214 }
1001610215
10017 assert(actual_type->id == ZigTypeIdInt);
10216 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt);
1001810217
1001910218 if (instr_is_comptime(target)) {
1002010219 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
......@@ -10334,6 +10533,15 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1033410533 }
1033510534 break;
1033610535 }
10536 case ConstCastResultIdFnArg: {
10537 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
10538 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'",
10539 cast_result->data.fn_arg.arg_index,
10540 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name),
10541 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name)));
10542 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg);
10543 break;
10544 }
1033710545 case ConstCastResultIdFnAlign: // TODO
1033810546 case ConstCastResultIdFnCC: // TODO
1033910547 case ConstCastResultIdFnVarArgs: // TODO
......@@ -10341,7 +10549,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1034110549 case ConstCastResultIdFnReturnType: // TODO
1034210550 case ConstCastResultIdFnArgCount: // TODO
1034310551 case ConstCastResultIdFnGenericArgCount: // TODO
10344 case ConstCastResultIdFnArg: // TODO
1034510552 case ConstCastResultIdFnArgNoAlias: // TODO
1034610553 case ConstCastResultIdUnresolvedInferredErrSet: // TODO
1034710554 case ConstCastResultIdAsyncAllocatorType: // TODO
......@@ -10370,6 +10577,121 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1037010577 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
1037110578 }
1037210579
10580 // cast from T to ?T
10581 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism
10582 if (wanted_type->id == ZigTypeIdOptional) {
10583 ZigType *wanted_child_type = wanted_type->data.maybe.child_type;
10584 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,
10585 false).id == ConstCastResultIdOk)
10586 {
10587 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
10588 } else if (actual_type->id == ZigTypeIdComptimeInt ||
10589 actual_type->id == ZigTypeIdComptimeFloat)
10590 {
10591 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
10592 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
10593 } else {
10594 return ira->codegen->invalid_instruction;
10595 }
10596 } else if (
10597 wanted_child_type->id == ZigTypeIdPointer &&
10598 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown &&
10599 actual_type->id == ZigTypeIdPointer &&
10600 actual_type->data.pointer.ptr_len == PtrLenSingle &&
10601 actual_type->data.pointer.child_type->id == ZigTypeIdArray)
10602 {
10603 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
10604 return ira->codegen->invalid_instruction;
10605 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
10606 return ira->codegen->invalid_instruction;
10607 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) &&
10608 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type,
10609 actual_type->data.pointer.child_type->data.array.child_type, source_node,
10610 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk)
10611 {
10612 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value,
10613 wanted_child_type);
10614 if (type_is_invalid(cast1->value.type))
10615 return ira->codegen->invalid_instruction;
10616 return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type);
10617 }
10618 }
10619 }
10620
10621 // T to E!T
10622 if (wanted_type->id == ZigTypeIdErrorUnion) {
10623 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
10624 source_node, false).id == ConstCastResultIdOk)
10625 {
10626 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
10627 } else if (actual_type->id == ZigTypeIdComptimeInt ||
10628 actual_type->id == ZigTypeIdComptimeFloat)
10629 {
10630 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
10631 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
10632 } else {
10633 return ira->codegen->invalid_instruction;
10634 }
10635 }
10636 }
10637
10638 // cast from T to E!?T
10639 if (wanted_type->id == ZigTypeIdErrorUnion &&
10640 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional &&
10641 actual_type->id != ZigTypeIdOptional)
10642 {
10643 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
10644 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk ||
10645 actual_type->id == ZigTypeIdNull ||
10646 actual_type->id == ZigTypeIdComptimeInt ||
10647 actual_type->id == ZigTypeIdComptimeFloat)
10648 {
10649 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
10650 if (type_is_invalid(cast1->value.type))
10651 return ira->codegen->invalid_instruction;
10652
10653 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
10654 if (type_is_invalid(cast2->value.type))
10655 return ira->codegen->invalid_instruction;
10656
10657 return cast2;
10658 }
10659 }
10660
10661
10662 // cast from comptime-known number to another number type
10663 if (instr_is_comptime(value) &&
10664 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt ||
10665 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) &&
10666 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt ||
10667 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat))
10668 {
10669 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) {
10670 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) {
10671 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
10672 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) {
10673 bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint);
10674 } else {
10675 float_init_bigint(&result->value.data.x_bigint, &value->value);
10676 }
10677 return result;
10678 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) {
10679 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
10680 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) {
10681 BigFloat bf;
10682 bigfloat_init_bigint(&bf, &value->value.data.x_bigint);
10683 float_init_bigfloat(&result->value, &bf);
10684 } else {
10685 float_init_float(&result->value, &value->value);
10686 }
10687 return result;
10688 }
10689 zig_unreachable();
10690 } else {
10691 return ira->codegen->invalid_instruction;
10692 }
10693 }
10694
1037310695 // widening conversion
1037410696 if (wanted_type->id == ZigTypeIdInt &&
1037510697 actual_type->id == ZigTypeIdInt &&
......@@ -10472,47 +10794,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1047210794 }
1047310795
1047410796
10475 // cast from T to ?T
10476 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism
10477 if (wanted_type->id == ZigTypeIdOptional) {
10478 ZigType *wanted_child_type = wanted_type->data.maybe.child_type;
10479 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,
10480 false).id == ConstCastResultIdOk)
10481 {
10482 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
10483 } else if (actual_type->id == ZigTypeIdComptimeInt ||
10484 actual_type->id == ZigTypeIdComptimeFloat)
10485 {
10486 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
10487 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
10488 } else {
10489 return ira->codegen->invalid_instruction;
10490 }
10491 } else if (
10492 wanted_child_type->id == ZigTypeIdPointer &&
10493 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown &&
10494 actual_type->id == ZigTypeIdPointer &&
10495 actual_type->data.pointer.ptr_len == PtrLenSingle &&
10496 actual_type->data.pointer.child_type->id == ZigTypeIdArray)
10497 {
10498 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
10499 return ira->codegen->invalid_instruction;
10500 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
10501 return ira->codegen->invalid_instruction;
10502 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) &&
10503 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type,
10504 actual_type->data.pointer.child_type->data.array.child_type, source_node,
10505 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk)
10506 {
10507 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value,
10508 wanted_child_type);
10509 if (type_is_invalid(cast1->value.type))
10510 return ira->codegen->invalid_instruction;
10511 return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type);
10512 }
10513 }
10514 }
10515
1051610797 // cast from null literal to maybe type
1051710798 if (wanted_type->id == ZigTypeIdOptional &&
1051810799 actual_type->id == ZigTypeIdNull)
......@@ -10520,23 +10801,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1052010801 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);
1052110802 }
1052210803
10523 // cast from child type of error type to error type
10524 if (wanted_type->id == ZigTypeIdErrorUnion) {
10525 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
10526 source_node, false).id == ConstCastResultIdOk)
10527 {
10528 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
10529 } else if (actual_type->id == ZigTypeIdComptimeInt ||
10530 actual_type->id == ZigTypeIdComptimeFloat)
10531 {
10532 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
10533 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
10534 } else {
10535 return ira->codegen->invalid_instruction;
10536 }
10537 }
10538 }
10539
1054010804 // cast from [N]T to E![]const T
1054110805 if (wanted_type->id == ZigTypeIdErrorUnion &&
1054210806 is_slice(wanted_type->data.error_union.payload_type) &&
......@@ -10568,54 +10832,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1056810832 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
1056910833 }
1057010834
10571 // cast from T to E!?T
10572 if (wanted_type->id == ZigTypeIdErrorUnion &&
10573 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional &&
10574 actual_type->id != ZigTypeIdOptional)
10575 {
10576 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
10577 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk ||
10578 actual_type->id == ZigTypeIdNull ||
10579 actual_type->id == ZigTypeIdComptimeInt ||
10580 actual_type->id == ZigTypeIdComptimeFloat)
10581 {
10582 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
10583 if (type_is_invalid(cast1->value.type))
10584 return ira->codegen->invalid_instruction;
10585
10586 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
10587 if (type_is_invalid(cast2->value.type))
10588 return ira->codegen->invalid_instruction;
10589
10590 return cast2;
10591 }
10592 }
10593
10594 // cast from number literal to another type
10595 if (actual_type->id == ZigTypeIdComptimeFloat ||
10596 actual_type->id == ZigTypeIdComptimeInt)
10597 {
10598 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) {
10599 CastOp op;
10600 if ((actual_type->id == ZigTypeIdComptimeFloat &&
10601 wanted_type->id == ZigTypeIdFloat) ||
10602 (actual_type->id == ZigTypeIdComptimeInt &&
10603 wanted_type->id == ZigTypeIdInt))
10604 {
10605 op = CastOpNumLitToConcrete;
10606 } else if (wanted_type->id == ZigTypeIdInt) {
10607 op = CastOpFloatToInt;
10608 } else if (wanted_type->id == ZigTypeIdFloat) {
10609 op = CastOpIntToFloat;
10610 } else {
10611 zig_unreachable();
10612 }
10613 return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false);
10614 } else {
10615 return ira->codegen->invalid_instruction;
10616 }
10617 }
10618
1061910835 // cast from typed number to integer or float literal.
1062010836 // works when the number is known at compile time
1062110837 if (instr_is_comptime(value) &&
......@@ -11014,8 +11230,12 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
1101411230 return ir_unreach_error(ira);
1101511231
1101611232 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);
11017 if (type_is_invalid(casted_value->value.type))
11233 if (type_is_invalid(casted_value->value.type) && ira->explicit_return_type_source_node != nullptr) {
11234 ErrorMsg *msg = ira->codegen->errors.last();
11235 add_error_note(ira->codegen, msg, ira->explicit_return_type_source_node,
11236 buf_sprintf("return type declared here"));
1101811237 return ir_unreach_error(ira);
11238 }
1101911239
1102011240 if (casted_value->value.special == ConstValSpecialRuntime &&
1102111241 casted_value->value.type->id == ZigTypeIdPointer &&
......@@ -11114,7 +11334,6 @@ static bool optional_value_is_null(ConstExprValue *val) {
1111411334}
1111511335
1111611336static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
11117 Error err;
1111811337 IrInstruction *op1 = bin_op_instruction->op1->child;
1111911338 if (type_is_invalid(op1->value.type))
1112011339 return ira->codegen->invalid_instruction;
......@@ -11308,10 +11527,19 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1130811527 if (casted_op2 == ira->codegen->invalid_instruction)
1130911528 return ira->codegen->invalid_instruction;
1131011529
11311 if ((err = type_resolve(ira->codegen, resolved_type, ResolveStatusZeroBitsKnown)))
11312 return ira->codegen->invalid_instruction;
11530 bool requires_comptime;
11531 switch (type_requires_comptime(ira->codegen, resolved_type)) {
11532 case ReqCompTimeYes:
11533 requires_comptime = true;
11534 break;
11535 case ReqCompTimeNo:
11536 requires_comptime = false;
11537 break;
11538 case ReqCompTimeInvalid:
11539 return ira->codegen->invalid_instruction;
11540 }
1131311541
11314 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type);
11542 bool one_possible_value = !requires_comptime && !type_has_bits(resolved_type);
1131511543 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) {
1131611544 ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad);
1131711545 if (op1_val == nullptr)
......@@ -12244,42 +12472,42 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruct
1224412472 ZigType *result_type = casted_init_value->value.type;
1224512473 if (type_is_invalid(result_type)) {
1224612474 result_type = ira->codegen->builtin_types.entry_invalid;
12247 } else {
12248 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusZeroBitsKnown))) {
12249 result_type = ira->codegen->builtin_types.entry_invalid;
12250 }
12475 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {
12476 ir_add_error_node(ira, source_node,
12477 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name)));
12478 result_type = ira->codegen->builtin_types.entry_invalid;
1225112479 }
1225212480
12253 if (!type_is_invalid(result_type)) {
12254 if (result_type->id == ZigTypeIdUnreachable ||
12255 result_type->id == ZigTypeIdOpaque)
12256 {
12481 switch (type_requires_comptime(ira->codegen, result_type)) {
12482 case ReqCompTimeInvalid:
12483 result_type = ira->codegen->builtin_types.entry_invalid;
12484 break;
12485 case ReqCompTimeYes: {
12486 var_class_requires_const = true;
12487 if (!var->gen_is_const && !is_comptime_var) {
1225712488 ir_add_error_node(ira, source_node,
12258 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name)));
12489 buf_sprintf("variable of type '%s' must be const or comptime",
12490 buf_ptr(&result_type->name)));
1225912491 result_type = ira->codegen->builtin_types.entry_invalid;
12260 } else if (type_requires_comptime(result_type)) {
12492 }
12493 break;
12494 }
12495 case ReqCompTimeNo:
12496 if (casted_init_value->value.special == ConstValSpecialStatic &&
12497 casted_init_value->value.type->id == ZigTypeIdFn &&
12498 casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
12499 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
12500 {
1226112501 var_class_requires_const = true;
12262 if (!var->gen_is_const && !is_comptime_var) {
12263 ir_add_error_node(ira, source_node,
12264 buf_sprintf("variable of type '%s' must be const or comptime",
12265 buf_ptr(&result_type->name)));
12502 if (!var->src_is_const && !is_comptime_var) {
12503 ErrorMsg *msg = ir_add_error_node(ira, source_node,
12504 buf_sprintf("functions marked inline must be stored in const or comptime var"));
12505 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;
12506 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
1226612507 result_type = ira->codegen->builtin_types.entry_invalid;
1226712508 }
12268 } else {
12269 if (casted_init_value->value.special == ConstValSpecialStatic &&
12270 casted_init_value->value.type->id == ZigTypeIdFn &&
12271 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
12272 {
12273 var_class_requires_const = true;
12274 if (!var->src_is_const && !is_comptime_var) {
12275 ErrorMsg *msg = ir_add_error_node(ira, source_node,
12276 buf_sprintf("functions marked inline must be stored in const or comptime var"));
12277 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;
12278 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
12279 result_type = ira->codegen->builtin_types.entry_invalid;
12280 }
12281 }
1228212509 }
12510 break;
1228312511 }
1228412512
1228512513 if (var->value->type != nullptr && !is_comptime_var) {
......@@ -12750,10 +12978,15 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1275012978 }
1275112979
1275212980 if (!comptime_arg) {
12753 if (type_requires_comptime(casted_arg->value.type)) {
12981 switch (type_requires_comptime(ira->codegen, casted_arg->value.type)) {
12982 case ReqCompTimeYes:
1275412983 ir_add_error(ira, casted_arg,
1275512984 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name)));
1275612985 return false;
12986 case ReqCompTimeInvalid:
12987 return false;
12988 case ReqCompTimeNo:
12989 break;
1275712990 }
1275812991
1275912992 casted_args[fn_type_id->param_count] = casted_arg;
......@@ -13226,12 +13459,15 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1322613459 inst_fn_type_id.return_type = specified_return_type;
1322713460 }
1322813461
13229 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusZeroBitsKnown)))
13230 return ira->codegen->invalid_instruction;
13231
13232 if (type_requires_comptime(specified_return_type)) {
13462 switch (type_requires_comptime(ira->codegen, specified_return_type)) {
13463 case ReqCompTimeYes:
1323313464 // Throw out our work and call the function as if it were comptime.
13234 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto);
13465 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr,
13466 true, FnInlineAuto);
13467 case ReqCompTimeInvalid:
13468 return ira->codegen->invalid_instruction;
13469 case ReqCompTimeNo:
13470 break;
1323513471 }
1323613472 }
1323713473 IrInstruction *async_allocator_inst = nullptr;
......@@ -13485,18 +13721,56 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
1348513721 return ErrorNone;
1348613722 }
1348713723
13488 if (dst_size > src_size) {
13489 ir_add_error_node(ira, source_node,
13490 buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes",
13491 dst_size, buf_ptr(&pointee->type->name), src_size));
13492 return ErrorSemanticAnalyzeFail;
13724 if (dst_size <= src_size) {
13725 Buf buf = BUF_INIT;
13726 buf_resize(&buf, src_size);
13727 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee);
13728 if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
13729 return err;
13730 return ErrorNone;
1349313731 }
1349413732
13495 Buf buf = BUF_INIT;
13496 buf_resize(&buf, src_size);
13497 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee);
13498 buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val);
13499 return ErrorNone;
13733 switch (ptr_val->data.x_ptr.special) {
13734 case ConstPtrSpecialInvalid:
13735 zig_unreachable();
13736 case ConstPtrSpecialRef: {
13737 ir_add_error_node(ira, source_node,
13738 buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes",
13739 dst_size, buf_ptr(&pointee->type->name), src_size));
13740 return ErrorSemanticAnalyzeFail;
13741 }
13742 case ConstPtrSpecialBaseArray: {
13743 ConstExprValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val;
13744 assert(array_val->type->id == ZigTypeIdArray);
13745 if (array_val->data.x_array.special != ConstArraySpecialNone)
13746 zig_panic("TODO");
13747 size_t elem_size = src_size;
13748 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index;
13749 src_size = elem_size * (array_val->type->data.array.len - elem_index);
13750 if (dst_size > src_size) {
13751 ir_add_error_node(ira, source_node,
13752 buf_sprintf("attempt to read %zu bytes from %s at index %" ZIG_PRI_usize " which is %zu bytes",
13753 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size));
13754 return ErrorSemanticAnalyzeFail;
13755 }
13756 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1);
13757 Buf buf = BUF_INIT;
13758 buf_resize(&buf, elem_count * elem_size);
13759 for (size_t i = 0; i < elem_count; i += 1) {
13760 ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i];
13761 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val);
13762 }
13763 if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
13764 return err;
13765 return ErrorNone;
13766 }
13767 case ConstPtrSpecialBaseStruct:
13768 case ConstPtrSpecialDiscard:
13769 case ConstPtrSpecialHardCodedAddr:
13770 case ConstPtrSpecialFunction:
13771 zig_panic("TODO");
13772 }
13773 zig_unreachable();
1350013774}
1350113775
1350213776static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
......@@ -14172,11 +14446,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1417214446
1417314447 } else {
1417414448 // runtime known element index
14175 if (type_requires_comptime(return_type)) {
14449 switch (type_requires_comptime(ira->codegen, return_type)) {
14450 case ReqCompTimeYes:
1417614451 ir_add_error(ira, elem_index,
1417714452 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known",
1417814453 buf_ptr(&return_type->data.pointer.child_type->name)));
1417914454 return ira->codegen->invalid_instruction;
14455 case ReqCompTimeInvalid:
14456 return ira->codegen->invalid_instruction;
14457 case ReqCompTimeNo:
14458 break;
1418014459 }
1418114460 if (ptr_align < abi_align) {
1418214461 if (elem_size >= ptr_align && elem_size % ptr_align == 0) {
......@@ -15233,9 +15512,19 @@ static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAs
1523315512 }
1523415513
1523515514 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) {
15236 input_list[i] = asm_instruction->input_list[i]->child;
15237 if (type_is_invalid(input_list[i]->value.type))
15515 IrInstruction *const input_value = asm_instruction->input_list[i]->child;
15516 if (type_is_invalid(input_value->value.type))
1523815517 return ira->codegen->invalid_instruction;
15518
15519 if (instr_is_comptime(input_value) &&
15520 (input_value->value.type->id == ZigTypeIdComptimeInt ||
15521 input_value->value.type->id == ZigTypeIdComptimeFloat)) {
15522 ir_add_error_node(ira, input_value->source_node,
15523 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value.type->name)));
15524 return ira->codegen->invalid_instruction;
15525 }
15526
15527 input_list[i] = input_value;
1523915528 }
1524015529
1524115530 IrInstruction *result = ir_build_asm(&ira->new_irb,
......@@ -17850,6 +18139,12 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct
1785018139 return ira->codegen->invalid_instruction;
1785118140 }
1785218141
18142 if (src_type->data.integral.bit_count == 0) {
18143 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
18144 bigint_init_unsigned(&result->value.data.x_bigint, 0);
18145 return result;
18146 }
18147
1785318148 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) {
1785418149 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned";
1785518150 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name)));
......@@ -17878,7 +18173,7 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct
1787818173 if (type_is_invalid(dest_type))
1787918174 return ira->codegen->invalid_instruction;
1788018175
17881 if (dest_type->id != ZigTypeIdInt) {
18176 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) {
1788218177 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name)));
1788318178 return ira->codegen->invalid_instruction;
1788418179 }
......@@ -17887,20 +18182,22 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct
1788718182 if (type_is_invalid(target->value.type))
1788818183 return ira->codegen->invalid_instruction;
1788918184
17890 if (target->value.type->id == ZigTypeIdComptimeInt) {
17891 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) {
17892 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpNumLitToConcrete, false);
17893 } else {
17894 return ira->codegen->invalid_instruction;
17895 }
17896 }
17897
17898 if (target->value.type->id != ZigTypeIdInt) {
18185 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) {
1789918186 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'",
1790018187 buf_ptr(&target->value.type->name)));
1790118188 return ira->codegen->invalid_instruction;
1790218189 }
1790318190
18191 if (instr_is_comptime(target)) {
18192 return ir_implicit_cast(ira, target, dest_type);
18193 }
18194
18195 if (dest_type->id == ZigTypeIdComptimeInt) {
18196 ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'",
18197 buf_ptr(&dest_type->name)));
18198 return ira->codegen->invalid_instruction;
18199 }
18200
1790418201 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type);
1790518202}
1790618203
......@@ -19216,7 +19513,6 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
1921619513}
1921719514
1921819515static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
19219 Error err;
1922019516 AstNode *proto_node = instruction->base.source_node;
1922119517 assert(proto_node->type == NodeTypeFnProto);
1922219518
......@@ -19255,11 +19551,8 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
1925519551 if (type_is_invalid(param_type_value->value.type))
1925619552 return ira->codegen->invalid_instruction;
1925719553 ZigType *param_type = ir_resolve_type(ira, param_type_value);
19258 if (type_is_invalid(param_type))
19259 return ira->codegen->invalid_instruction;
19260 if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown)))
19261 return ira->codegen->invalid_instruction;
19262 if (type_requires_comptime(param_type)) {
19554 switch (type_requires_comptime(ira->codegen, param_type)) {
19555 case ReqCompTimeYes:
1926319556 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1926419557 ir_add_error(ira, param_type_value,
1926519558 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
......@@ -19269,6 +19562,10 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
1926919562 param_info->type = param_type;
1927019563 fn_type_id.next_param_index += 1;
1927119564 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id));
19565 case ReqCompTimeInvalid:
19566 return ira->codegen->invalid_instruction;
19567 case ReqCompTimeNo:
19568 break;
1927219569 }
1927319570 if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) {
1927419571 ir_add_error(ira, param_type_value,
......@@ -19711,6 +20008,8 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
1971120008}
1971220009
1971320010static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
20011 if (val->special == ConstValSpecialUndef)
20012 val->special = ConstValSpecialStatic;
1971420013 assert(val->special == ConstValSpecialStatic);
1971520014 switch (val->type->id) {
1971620015 case ZigTypeIdInvalid:
......@@ -19780,7 +20079,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1978020079 zig_unreachable();
1978120080}
1978220081
19783static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
20082static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
20083 Error err;
1978420084 assert(val->special == ConstValSpecialStatic);
1978520085 switch (val->type->id) {
1978620086 case ZigTypeIdInvalid:
......@@ -19797,30 +20097,60 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1979720097 case ZigTypeIdPromise:
1979820098 zig_unreachable();
1979920099 case ZigTypeIdVoid:
19800 return;
20100 return ErrorNone;
1980120101 case ZigTypeIdBool:
1980220102 val->data.x_bool = (buf[0] != 0);
19803 return;
20103 return ErrorNone;
1980420104 case ZigTypeIdInt:
1980520105 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count,
19806 codegen->is_big_endian, val->type->data.integral.is_signed);
19807 return;
20106 ira->codegen->is_big_endian, val->type->data.integral.is_signed);
20107 return ErrorNone;
1980820108 case ZigTypeIdFloat:
19809 float_read_ieee597(val, buf, codegen->is_big_endian);
19810 return;
20109 float_read_ieee597(val, buf, ira->codegen->is_big_endian);
20110 return ErrorNone;
1981120111 case ZigTypeIdPointer:
1981220112 {
1981320113 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
1981420114 BigInt bn;
19815 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count,
19816 codegen->is_big_endian, false);
20115 bigint_read_twos_complement(&bn, buf, ira->codegen->builtin_types.entry_usize->data.integral.bit_count,
20116 ira->codegen->is_big_endian, false);
1981720117 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
19818 return;
20118 return ErrorNone;
1981920119 }
1982020120 case ZigTypeIdArray:
1982120121 zig_panic("TODO buf_read_value_bytes array type");
1982220122 case ZigTypeIdStruct:
19823 zig_panic("TODO buf_read_value_bytes struct type");
20123 switch (val->type->data.structure.layout) {
20124 case ContainerLayoutAuto: {
20125 ErrorMsg *msg = ir_add_error_node(ira, source_node,
20126 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted",
20127 buf_ptr(&val->type->name)));
20128 add_error_note(ira->codegen, msg, val->type->data.structure.decl_node,
20129 buf_sprintf("declared here"));
20130 return ErrorSemanticAnalyzeFail;
20131 }
20132 case ContainerLayoutExtern: {
20133 size_t src_field_count = val->type->data.structure.src_field_count;
20134 val->data.x_struct.fields = create_const_vals(src_field_count);
20135 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
20136 ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
20137 field_val->special = ConstValSpecialStatic;
20138 TypeStructField *type_field = &val->type->data.structure.fields[field_i];
20139 field_val->type = type_field->type_entry;
20140 if (type_field->gen_index == SIZE_MAX)
20141 continue;
20142 size_t offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, val->type->type_ref,
20143 type_field->gen_index);
20144 uint8_t *new_buf = buf + offset;
20145 if ((err = buf_read_value_bytes(ira, source_node, new_buf, field_val)))
20146 return err;
20147 }
20148 return ErrorNone;
20149 }
20150 case ContainerLayoutPacked:
20151 zig_panic("TODO buf_read_value_bytes packed struct");
20152 }
20153 zig_unreachable();
1982420154 case ZigTypeIdOptional:
1982520155 zig_panic("TODO buf_read_value_bytes maybe type");
1982620156 case ZigTypeIdErrorUnion:
......@@ -19923,7 +20253,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
1992320253 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
1992420254 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes);
1992520255 buf_write_value_bytes(ira->codegen, buf, val);
19926 buf_read_value_bytes(ira->codegen, buf, &result->value);
20256 if ((err = buf_read_value_bytes(ira, instruction->base.source_node, buf, &result->value)))
20257 return ira->codegen->invalid_instruction;
1992720258 return result;
1992820259 }
1992920260
......@@ -20093,6 +20424,9 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
2009320424 return ira->codegen->invalid_instruction;
2009420425 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown)))
2009520426 return ira->codegen->invalid_instruction;
20427 if (!type_has_bits(child_type)) {
20428 align_bytes = 0;
20429 }
2009620430 } else {
2009720431 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
2009820432 return ira->codegen->invalid_instruction;
......@@ -20692,6 +21026,63 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS
2069221026 return result;
2069321027}
2069421028
21029static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) {
21030 ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
21031 if (type_is_invalid(int_type))
21032 return ira->codegen->invalid_instruction;
21033
21034 IrInstruction *op = instruction->op->child;
21035 if (type_is_invalid(op->value.type))
21036 return ira->codegen->invalid_instruction;
21037
21038 if (int_type->id != ZigTypeIdInt) {
21039 ir_add_error(ira, instruction->type,
21040 buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
21041 return ira->codegen->invalid_instruction;
21042 }
21043
21044 if (int_type->data.integral.bit_count % 8 != 0) {
21045 ir_add_error(ira, instruction->type,
21046 buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8",
21047 buf_ptr(&int_type->name), int_type->data.integral.bit_count));
21048 return ira->codegen->invalid_instruction;
21049 }
21050
21051 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
21052 if (type_is_invalid(casted_op->value.type))
21053 return ira->codegen->invalid_instruction;
21054
21055 if (int_type->data.integral.bit_count == 0) {
21056 IrInstruction *result = ir_const(ira, &instruction->base, int_type);
21057 bigint_init_unsigned(&result->value.data.x_bigint, 0);
21058 return result;
21059 }
21060
21061 if (int_type->data.integral.bit_count == 8) {
21062 return casted_op;
21063 }
21064
21065 if (instr_is_comptime(casted_op)) {
21066 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
21067 if (!val)
21068 return ira->codegen->invalid_instruction;
21069
21070 IrInstruction *result = ir_const(ira, &instruction->base, int_type);
21071 size_t buf_size = int_type->data.integral.bit_count / 8;
21072 uint8_t *buf = allocate_nonzero<uint8_t>(buf_size);
21073 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true);
21074 bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false,
21075 int_type->data.integral.is_signed);
21076 return result;
21077 }
21078
21079 IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope,
21080 instruction->base.source_node, nullptr, casted_op);
21081 result->value.type = int_type;
21082 return result;
21083}
21084
21085
2069521086static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) {
2069621087 Error err;
2069721088 IrInstruction *target = instruction->target->child;
......@@ -21027,6 +21418,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2102721418 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);
2102821419 case IrInstructionIdSqrt:
2102921420 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);
21421 case IrInstructionIdBswap:
21422 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction);
2103021423 case IrInstructionIdIntToErr:
2103121424 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);
2103221425 case IrInstructionIdErrToInt:
......@@ -21063,6 +21456,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
2106321456 ZigFn *fn_entry = exec_fn_entry(old_exec);
2106421457 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
2106521458 ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type;
21459 ira->explicit_return_type_source_node = expected_type_source_node;
2106621460
2106721461 ira->old_irb.codegen = codegen;
2106821462 ira->old_irb.exec = old_exec;
......@@ -21247,6 +21641,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2124721641 case IrInstructionIdCoroPromise:
2124821642 case IrInstructionIdPromiseResultType:
2124921643 case IrInstructionIdSqrt:
21644 case IrInstructionIdBswap:
2125021645 case IrInstructionIdAtomicLoad:
2125121646 case IrInstructionIdIntCast:
2125221647 case IrInstructionIdFloatCast:
src/ir_print.cpp+15
......@@ -1323,6 +1323,18 @@ static void ir_print_sqrt(IrPrint *irp, IrInstructionSqrt *instruction) {
13231323 fprintf(irp->f, ")");
13241324}
13251325
1326static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) {
1327 fprintf(irp->f, "@bswap(");
1328 if (instruction->type != nullptr) {
1329 ir_print_other_instruction(irp, instruction->type);
1330 } else {
1331 fprintf(irp->f, "null");
1332 }
1333 fprintf(irp->f, ",");
1334 ir_print_other_instruction(irp, instruction->op);
1335 fprintf(irp->f, ")");
1336}
1337
13261338static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
13271339 ir_print_prefix(irp, instruction);
13281340 switch (instruction->id) {
......@@ -1736,6 +1748,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
17361748 case IrInstructionIdSqrt:
17371749 ir_print_sqrt(irp, (IrInstructionSqrt *)instruction);
17381750 break;
1751 case IrInstructionIdBswap:
1752 ir_print_bswap(irp, (IrInstructionBswap *)instruction);
1753 break;
17391754 case IrInstructionIdAtomicLoad:
17401755 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
17411756 break;
src/link.cpp+7
......@@ -150,6 +150,10 @@ static const char *getLDMOption(const ZigTarget *t) {
150150 if (t->env_type == ZigLLVM_GNUX32) {
151151 return "elf32_x86_64";
152152 }
153 // Any target elf will use the freebsd osabi if suffixed with "_fbsd".
154 if (t->os == OsFreeBSD) {
155 return "elf_x86_64_fbsd";
156 }
153157 return "elf_x86_64";
154158 default:
155159 zig_unreachable();
......@@ -191,6 +195,9 @@ static Buf *try_dynamic_linker_path(const char *ld_name) {
191195}
192196
193197static Buf *get_dynamic_linker_path(CodeGen *g) {
198 if (g->zig_target.os == OsFreeBSD) {
199 return buf_create_from_str("/libexec/ld-elf.so.1");
200 }
194201 if (g->is_native_target && g->zig_target.arch.arch == ZigLLVM_x86_64) {
195202 static const char *ld_names[] = {
196203 "ld-linux-x86-64.so.2",
src/main.cpp+1-8
......@@ -466,16 +466,9 @@ int main(int argc, char **argv) {
466466 "\n"
467467 "General Options:\n"
468468 " --help Print this help and exit\n"
469 " --build-file [file] Override path to build.zig\n"
470 " --cache-dir [path] Override path to cache directory\n"
471469 " --verbose Print commands before executing them\n"
472 " --verbose-tokenize Enable compiler debug output for tokenization\n"
473 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
474 " --verbose-link Enable compiler debug output for linking\n"
475 " --verbose-ir Enable compiler debug output for Zig IR\n"
476 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
477 " --verbose-cimport Enable compiler debug output for C imports\n"
478470 " --prefix [path] Override default install prefix\n"
471 " --search-prefix [path] Add a path to look for binaries, libraries, headers\n"
479472 "\n"
480473 "Project-specific options become available when the build file is found.\n"
481474 "\n"
src/os.cpp+29-9
......@@ -50,10 +50,13 @@ typedef SSIZE_T ssize_t;
5050
5151#endif
5252
53#if defined(ZIG_OS_LINUX)
53#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD)
5454#include <link.h>
5555#endif
5656
57#if defined(ZIG_OS_FREEBSD)
58#include <sys/sysctl.h>
59#endif
5760
5861#if defined(__MACH__)
5962#include <mach/clock.h>
......@@ -75,7 +78,9 @@ static clock_serv_t cclock;
7578#if defined(__APPLE__) && !defined(environ)
7679#include <crt_externs.h>
7780#define environ (*_NSGetEnviron())
78#endif
81#elif defined(ZIG_OS_FREEBSD)
82extern char **environ;
83#endif
7984
8085#if defined(ZIG_OS_POSIX)
8186static void populate_termination(Termination *term, int status) {
......@@ -188,14 +193,20 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) {
188193 size_t len = buf_len(full_path);
189194 if (len != 0) {
190195 size_t last_index = len - 1;
191 if (os_is_sep(buf_ptr(full_path)[last_index])) {
196 char last_char = buf_ptr(full_path)[last_index];
197 if (os_is_sep(last_char)) {
198 if (last_index == 0) {
199 if (out_dirname) buf_init_from_mem(out_dirname, &last_char, 1);
200 if (out_basename) buf_init_from_str(out_basename, "");
201 return;
202 }
192203 last_index -= 1;
193204 }
194205 for (size_t i = last_index;;) {
195206 uint8_t c = buf_ptr(full_path)[i];
196207 if (os_is_sep(c)) {
197208 if (out_dirname) {
198 buf_init_from_mem(out_dirname, buf_ptr(full_path), i);
209 buf_init_from_mem(out_dirname, buf_ptr(full_path), (i == 0) ? 1 : i);
199210 }
200211 if (out_basename) {
201212 buf_init_from_mem(out_basename, buf_ptr(full_path) + i + 1, buf_len(full_path) - (i + 1));
......@@ -1438,6 +1449,15 @@ Error os_self_exe_path(Buf *out_path) {
14381449 }
14391450 buf_resize(out_path, amt);
14401451 return ErrorNone;
1452#elif defined(ZIG_OS_FREEBSD)
1453 buf_resize(out_path, PATH_MAX);
1454 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
1455 size_t cb = PATH_MAX;
1456 if (sysctl(mib, 4, buf_ptr(out_path), &cb, nullptr, 0) != 0) {
1457 return ErrorUnexpected;
1458 }
1459 buf_resize(out_path, cb - 1);
1460 return ErrorNone;
14411461#endif
14421462 return ErrorFileNotFound;
14431463}
......@@ -1743,7 +1763,7 @@ Error os_get_app_data_dir(Buf *out_path, const char *appname) {
17431763 buf_resize(out_path, 0);
17441764 buf_appendf(out_path, "%s/Library/Application Support/%s", home_dir, appname);
17451765 return ErrorNone;
1746#elif defined(ZIG_OS_LINUX)
1766#elif defined(ZIG_OS_POSIX)
17471767 const char *home_dir = getenv("HOME");
17481768 if (home_dir == nullptr) {
17491769 // TODO use /etc/passwd
......@@ -1756,7 +1776,7 @@ Error os_get_app_data_dir(Buf *out_path, const char *appname) {
17561776}
17571777
17581778
1759#if defined(ZIG_OS_LINUX)
1779#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD)
17601780static int self_exe_shared_libs_callback(struct dl_phdr_info *info, size_t size, void *data) {
17611781 ZigList<Buf *> *libs = reinterpret_cast< ZigList<Buf *> *>(data);
17621782 if (info->dlpi_name[0] == '/') {
......@@ -1767,7 +1787,7 @@ static int self_exe_shared_libs_callback(struct dl_phdr_info *info, size_t size,
17671787#endif
17681788
17691789Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
1770#if defined(ZIG_OS_LINUX)
1790#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD)
17711791 paths.resize(0);
17721792 dl_iterate_phdr(self_exe_shared_libs_callback, &paths);
17731793 return ErrorNone;
......@@ -1936,7 +1956,7 @@ Error os_file_mtime(OsFile file, OsTimeStamp *mtime) {
19361956 mtime->sec = (((ULONGLONG) last_write_time.dwHighDateTime) << 32) + last_write_time.dwLowDateTime;
19371957 mtime->nsec = 0;
19381958 return ErrorNone;
1939#elif defined(ZIG_OS_LINUX)
1959#elif defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD)
19401960 struct stat statbuf;
19411961 if (fstat(file, &statbuf) == -1)
19421962 return ErrorFileSystem;
......@@ -1976,7 +1996,7 @@ Error os_file_read(OsFile file, void *ptr, size_t *len) {
19761996 case EFAULT:
19771997 zig_unreachable();
19781998 case EISDIR:
1979 zig_unreachable();
1999 return ErrorIsDir;
19802000 default:
19812001 return ErrorFileSystem;
19822002 }
src/os.hpp+2
......@@ -23,6 +23,8 @@
2323#define ZIG_OS_WINDOWS
2424#elif defined(__linux__)
2525#define ZIG_OS_LINUX
26#elif defined(__FreeBSD__)
27#define ZIG_OS_FREEBSD
2628#else
2729#define ZIG_OS_UNKNOWN
2830#endif
src/parser.cpp+13-13
......@@ -91,7 +91,7 @@ static Token *ast_parse_break_label(ParseContext *pc);
9191static Token *ast_parse_block_label(ParseContext *pc);
9292static AstNode *ast_parse_field_init(ParseContext *pc);
9393static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94static AstNode *ast_parse_section(ParseContext *pc);
94static AstNode *ast_parse_link_section(ParseContext *pc);
9595static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
9696static AstNode *ast_parse_param_decl(ParseContext *pc);
9797static AstNode *ast_parse_param_type(ParseContext *pc);
......@@ -775,7 +775,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
775775 return nullptr;
776776}
777777
778// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Section? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
778// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
779779static AstNode *ast_parse_fn_proto(ParseContext *pc) {
780780 Token *first = peek_token(pc);
781781 AstNodeFnProto fn_cc;
......@@ -806,7 +806,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
806806 expect_token(pc, TokenIdRParen);
807807
808808 AstNode *align_expr = ast_parse_byte_align(pc);
809 AstNode *section_expr = ast_parse_section(pc);
809 AstNode *section_expr = ast_parse_link_section(pc);
810810 Token *var = eat_token_if(pc, TokenIdKeywordVar);
811811 Token *exmark = nullptr;
812812 AstNode *return_type = nullptr;
......@@ -842,7 +842,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
842842 return res;
843843}
844844
845// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? Section? (EQUAL Expr)? SEMICOLON
845// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
846846static AstNode *ast_parse_var_decl(ParseContext *pc) {
847847 Token *first = eat_token_if(pc, TokenIdKeywordConst);
848848 if (first == nullptr)
......@@ -856,7 +856,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
856856 type_expr = ast_expect(pc, ast_parse_type_expr);
857857
858858 AstNode *align_expr = ast_parse_byte_align(pc);
859 AstNode *section_expr = ast_parse_section(pc);
859 AstNode *section_expr = ast_parse_link_section(pc);
860860 AstNode *expr = nullptr;
861861 if (eat_token_if(pc, TokenIdEq) != nullptr)
862862 expr = ast_expect(pc, ast_parse_expr);
......@@ -1490,8 +1490,8 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
14901490}
14911491
14921492// SuffixExpr
1493// <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
1494// / PrimaryTypeExpr (SuffixOp / FnCallArgumnets)*
1493// <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments
1494// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
14951495static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
14961496 AstNode *async_call = ast_parse_async_prefix(pc);
14971497 if (async_call != nullptr) {
......@@ -1599,7 +1599,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
15991599}
16001600
16011601// PrimaryTypeExpr
1602// <- BUILTININDENTIFIER FnCallArgumnets
1602// <- BUILTINIDENTIFIER FnCallArguments
16031603// / CHAR_LITERAL
16041604// / ContainerDecl
16051605// / ErrorSetDecl
......@@ -1978,7 +1978,7 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
19781978 return res;
19791979}
19801980
1981// AsmInput <- COLON AsmInputList AsmCloppers?
1981// AsmInput <- COLON AsmInputList AsmClobbers?
19821982static AstNode *ast_parse_asm_input(ParseContext *pc) {
19831983 if (eat_token_if(pc, TokenIdColon) == nullptr)
19841984 return nullptr;
......@@ -2011,7 +2011,7 @@ static AsmInput *ast_parse_asm_input_item(ParseContext *pc) {
20112011 return res;
20122012}
20132013
2014// AsmCloppers <- COLON StringList
2014// AsmClobbers <- COLON StringList
20152015static AstNode *ast_parse_asm_cloppers(ParseContext *pc) {
20162016 if (eat_token_if(pc, TokenIdColon) == nullptr)
20172017 return nullptr;
......@@ -2080,8 +2080,8 @@ static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
20802080 return expr;
20812081}
20822082
2083// Section <- KEYWORD_section LPAREN Expr RPAREN
2084static AstNode *ast_parse_section(ParseContext *pc) {
2083// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
2084static AstNode *ast_parse_link_section(ParseContext *pc) {
20852085 Token *first = eat_token_if(pc, TokenIdKeywordLinkSection);
20862086 if (first == nullptr)
20872087 return nullptr;
......@@ -2742,7 +2742,7 @@ static AstNode *ast_parse_async_prefix(ParseContext *pc) {
27422742 return res;
27432743}
27442744
2745// FnCallArgumnets <- LPAREN ExprList RPAREN
2745// FnCallArguments <- LPAREN ExprList RPAREN
27462746static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc) {
27472747 Token *paren = eat_token_if(pc, TokenIdLParen);
27482748 if (paren == nullptr)
src/target.cpp+62-1
......@@ -754,6 +754,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
754754 case OsLinux:
755755 case OsMacOSX:
756756 case OsZen:
757 case OsFreeBSD:
757758 case OsOpenBSD:
758759 switch (id) {
759760 case CIntTypeShort:
......@@ -790,7 +791,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
790791 case OsAnanas:
791792 case OsCloudABI:
792793 case OsDragonFly:
793 case OsFreeBSD:
794794 case OsIOS:
795795 case OsKFreeBSD:
796796 case OsLv2:
......@@ -1028,3 +1028,64 @@ const char *arch_stack_pointer_register_name(const ArchType *arch) {
10281028 }
10291029 zig_unreachable();
10301030}
1031
1032bool target_is_arm(const ZigTarget *target) {
1033 switch (target->arch.arch) {
1034 case ZigLLVM_UnknownArch:
1035 zig_unreachable();
1036 case ZigLLVM_aarch64:
1037 case ZigLLVM_arm:
1038 case ZigLLVM_thumb:
1039 case ZigLLVM_aarch64_be:
1040 case ZigLLVM_armeb:
1041 case ZigLLVM_thumbeb:
1042 return true;
1043
1044 case ZigLLVM_x86:
1045 case ZigLLVM_x86_64:
1046 case ZigLLVM_amdgcn:
1047 case ZigLLVM_amdil:
1048 case ZigLLVM_amdil64:
1049 case ZigLLVM_arc:
1050 case ZigLLVM_avr:
1051 case ZigLLVM_bpfeb:
1052 case ZigLLVM_bpfel:
1053 case ZigLLVM_hexagon:
1054 case ZigLLVM_lanai:
1055 case ZigLLVM_hsail:
1056 case ZigLLVM_hsail64:
1057 case ZigLLVM_kalimba:
1058 case ZigLLVM_le32:
1059 case ZigLLVM_le64:
1060 case ZigLLVM_mips:
1061 case ZigLLVM_mips64:
1062 case ZigLLVM_mips64el:
1063 case ZigLLVM_mipsel:
1064 case ZigLLVM_msp430:
1065 case ZigLLVM_nios2:
1066 case ZigLLVM_nvptx:
1067 case ZigLLVM_nvptx64:
1068 case ZigLLVM_ppc64le:
1069 case ZigLLVM_r600:
1070 case ZigLLVM_renderscript32:
1071 case ZigLLVM_renderscript64:
1072 case ZigLLVM_riscv32:
1073 case ZigLLVM_riscv64:
1074 case ZigLLVM_shave:
1075 case ZigLLVM_sparc:
1076 case ZigLLVM_sparcel:
1077 case ZigLLVM_sparcv9:
1078 case ZigLLVM_spir:
1079 case ZigLLVM_spir64:
1080 case ZigLLVM_systemz:
1081 case ZigLLVM_tce:
1082 case ZigLLVM_tcele:
1083 case ZigLLVM_wasm32:
1084 case ZigLLVM_wasm64:
1085 case ZigLLVM_xcore:
1086 case ZigLLVM_ppc:
1087 case ZigLLVM_ppc64:
1088 return false;
1089 }
1090 zig_unreachable();
1091}
src/target.hpp+2
......@@ -122,4 +122,6 @@ Buf *target_dynamic_linker(ZigTarget *target);
122122bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
123123ZigLLVM_OSType get_llvm_os_type(Os os_type);
124124
125bool target_is_arm(const ZigTarget *target);
126
125127#endif
src/translate_c.cpp+8
......@@ -4784,6 +4784,14 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
47844784
47854785 clang_argv.append(target_file);
47864786
4787 if (codegen->verbose_cimport) {
4788 fprintf(stderr, "clang");
4789 for (size_t i = 0; i < clang_argv.length; i += 1) {
4790 fprintf(stderr, " %s", clang_argv.at(i));
4791 }
4792 fprintf(stderr, "\n");
4793 }
4794
47874795 // to make the [start...end] argument work
47884796 clang_argv.append(nullptr);
47894797
src/util.hpp+11
......@@ -158,6 +158,17 @@ static inline bool is_power_of_2(uint64_t x) {
158158 return x != 0 && ((x & (~x + 1)) == x);
159159}
160160
161static inline uint64_t round_to_next_power_of_2(uint64_t x) {
162 --x;
163 x |= x >> 1;
164 x |= x >> 2;
165 x |= x >> 4;
166 x |= x >> 8;
167 x |= x >> 16;
168 x |= x >> 32;
169 return x + 1;
170}
171
161172uint32_t int_hash(int i);
162173bool int_eq(int a, int b);
163174uint32_t uint64_hash(uint64_t i);
src/zig_llvm.cpp+161-14
......@@ -680,20 +680,6 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
680680 llvm::cl::ParseCommandLineOptions(argc, argv);
681681}
682682
683
684static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
685static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, "");
686static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, "");
687static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, "");
688static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
689static_assert((Triple::SubArchType)ZigLLVM_MipsSubArch_r6 == Triple::MipsSubArch_r6, "");
690
691static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, "");
692static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, "");
693static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, "");
694static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, "");
695static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");
696
697683const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) {
698684 return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin();
699685}
......@@ -924,3 +910,164 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
924910 assert(false); // unreachable
925911 abort();
926912}
913
914static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");
915static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, "");
916static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, "");
917static_assert((Triple::ArchType)ZigLLVM_aarch64 == Triple::aarch64, "");
918static_assert((Triple::ArchType)ZigLLVM_aarch64_be == Triple::aarch64_be, "");
919static_assert((Triple::ArchType)ZigLLVM_arc == Triple::arc, "");
920static_assert((Triple::ArchType)ZigLLVM_avr == Triple::avr, "");
921static_assert((Triple::ArchType)ZigLLVM_bpfel == Triple::bpfel, "");
922static_assert((Triple::ArchType)ZigLLVM_bpfeb == Triple::bpfeb, "");
923static_assert((Triple::ArchType)ZigLLVM_hexagon == Triple::hexagon, "");
924static_assert((Triple::ArchType)ZigLLVM_mips == Triple::mips, "");
925static_assert((Triple::ArchType)ZigLLVM_mipsel == Triple::mipsel, "");
926static_assert((Triple::ArchType)ZigLLVM_mips64 == Triple::mips64, "");
927static_assert((Triple::ArchType)ZigLLVM_mips64el == Triple::mips64el, "");
928static_assert((Triple::ArchType)ZigLLVM_msp430 == Triple::msp430, "");
929static_assert((Triple::ArchType)ZigLLVM_nios2 == Triple::nios2, "");
930static_assert((Triple::ArchType)ZigLLVM_ppc == Triple::ppc, "");
931static_assert((Triple::ArchType)ZigLLVM_ppc64 == Triple::ppc64, "");
932static_assert((Triple::ArchType)ZigLLVM_ppc64le == Triple::ppc64le, "");
933static_assert((Triple::ArchType)ZigLLVM_r600 == Triple::r600, "");
934static_assert((Triple::ArchType)ZigLLVM_amdgcn == Triple::amdgcn, "");
935static_assert((Triple::ArchType)ZigLLVM_riscv32 == Triple::riscv32, "");
936static_assert((Triple::ArchType)ZigLLVM_riscv64 == Triple::riscv64, "");
937static_assert((Triple::ArchType)ZigLLVM_sparc == Triple::sparc, "");
938static_assert((Triple::ArchType)ZigLLVM_sparcv9 == Triple::sparcv9, "");
939static_assert((Triple::ArchType)ZigLLVM_sparcel == Triple::sparcel, "");
940static_assert((Triple::ArchType)ZigLLVM_systemz == Triple::systemz, "");
941static_assert((Triple::ArchType)ZigLLVM_tce == Triple::tce, "");
942static_assert((Triple::ArchType)ZigLLVM_tcele == Triple::tcele, "");
943static_assert((Triple::ArchType)ZigLLVM_thumb == Triple::thumb, "");
944static_assert((Triple::ArchType)ZigLLVM_thumbeb == Triple::thumbeb, "");
945static_assert((Triple::ArchType)ZigLLVM_x86 == Triple::x86, "");
946static_assert((Triple::ArchType)ZigLLVM_x86_64 == Triple::x86_64, "");
947static_assert((Triple::ArchType)ZigLLVM_xcore == Triple::xcore, "");
948static_assert((Triple::ArchType)ZigLLVM_nvptx == Triple::nvptx, "");
949static_assert((Triple::ArchType)ZigLLVM_nvptx64 == Triple::nvptx64, "");
950static_assert((Triple::ArchType)ZigLLVM_le32 == Triple::le32, "");
951static_assert((Triple::ArchType)ZigLLVM_le64 == Triple::le64, "");
952static_assert((Triple::ArchType)ZigLLVM_amdil == Triple::amdil, "");
953static_assert((Triple::ArchType)ZigLLVM_amdil64 == Triple::amdil64, "");
954static_assert((Triple::ArchType)ZigLLVM_hsail == Triple::hsail, "");
955static_assert((Triple::ArchType)ZigLLVM_hsail64 == Triple::hsail64, "");
956static_assert((Triple::ArchType)ZigLLVM_spir == Triple::spir, "");
957static_assert((Triple::ArchType)ZigLLVM_spir64 == Triple::spir64, "");
958static_assert((Triple::ArchType)ZigLLVM_kalimba == Triple::kalimba, "");
959static_assert((Triple::ArchType)ZigLLVM_shave == Triple::shave, "");
960static_assert((Triple::ArchType)ZigLLVM_lanai == Triple::lanai, "");
961static_assert((Triple::ArchType)ZigLLVM_wasm32 == Triple::wasm32, "");
962static_assert((Triple::ArchType)ZigLLVM_wasm64 == Triple::wasm64, "");
963static_assert((Triple::ArchType)ZigLLVM_renderscript32 == Triple::renderscript32, "");
964static_assert((Triple::ArchType)ZigLLVM_renderscript64 == Triple::renderscript64, "");
965static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
966
967static_assert((Triple::SubArchType)ZigLLVM_NoSubArch == Triple::NoSubArch, "");
968static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_4a == Triple::ARMSubArch_v8_4a, "");
969static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_3a == Triple::ARMSubArch_v8_3a, "");
970static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_2a == Triple::ARMSubArch_v8_2a, "");
971static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1a == Triple::ARMSubArch_v8_1a, "");
972static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8 == Triple::ARMSubArch_v8, "");
973static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8r == Triple::ARMSubArch_v8r, "");
974static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_baseline == Triple::ARMSubArch_v8m_baseline, "");
975static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_mainline == Triple::ARMSubArch_v8m_mainline, "");
976static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7 == Triple::ARMSubArch_v7, "");
977static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7em == Triple::ARMSubArch_v7em, "");
978static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7m == Triple::ARMSubArch_v7m, "");
979static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7s == Triple::ARMSubArch_v7s, "");
980static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7k == Triple::ARMSubArch_v7k, "");
981static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7ve == Triple::ARMSubArch_v7ve, "");
982static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6 == Triple::ARMSubArch_v6, "");
983static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6m == Triple::ARMSubArch_v6m, "");
984static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6k == Triple::ARMSubArch_v6k, "");
985static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6t2 == Triple::ARMSubArch_v6t2, "");
986static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5 == Triple::ARMSubArch_v5, "");
987static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5te == Triple::ARMSubArch_v5te, "");
988static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v4t == Triple::ARMSubArch_v4t, "");
989static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v3 == Triple::KalimbaSubArch_v3, "");
990static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v4 == Triple::KalimbaSubArch_v4, "");
991static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
992static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
993static_assert((Triple::SubArchType)ZigLLVM_MipsSubArch_r6 == Triple::MipsSubArch_r6, "");
994
995static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor, "");
996static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, "");
997static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, "");
998static_assert((Triple::VendorType)ZigLLVM_SCEI == Triple::SCEI, "");
999static_assert((Triple::VendorType)ZigLLVM_BGP == Triple::BGP, "");
1000static_assert((Triple::VendorType)ZigLLVM_BGQ == Triple::BGQ, "");
1001static_assert((Triple::VendorType)ZigLLVM_Freescale == Triple::Freescale, "");
1002static_assert((Triple::VendorType)ZigLLVM_IBM == Triple::IBM, "");
1003static_assert((Triple::VendorType)ZigLLVM_ImaginationTechnologies == Triple::ImaginationTechnologies, "");
1004static_assert((Triple::VendorType)ZigLLVM_MipsTechnologies == Triple::MipsTechnologies, "");
1005static_assert((Triple::VendorType)ZigLLVM_NVIDIA == Triple::NVIDIA, "");
1006static_assert((Triple::VendorType)ZigLLVM_CSR == Triple::CSR, "");
1007static_assert((Triple::VendorType)ZigLLVM_Myriad == Triple::Myriad, "");
1008static_assert((Triple::VendorType)ZigLLVM_AMD == Triple::AMD, "");
1009static_assert((Triple::VendorType)ZigLLVM_Mesa == Triple::Mesa, "");
1010static_assert((Triple::VendorType)ZigLLVM_SUSE == Triple::SUSE, "");
1011static_assert((Triple::VendorType)ZigLLVM_OpenEmbedded == Triple::OpenEmbedded, "");
1012static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, "");
1013
1014static_assert((Triple::OSType)ZigLLVM_UnknownOS == Triple::UnknownOS, "");
1015static_assert((Triple::OSType)ZigLLVM_Ananas == Triple::Ananas, "");
1016static_assert((Triple::OSType)ZigLLVM_CloudABI == Triple::CloudABI, "");
1017static_assert((Triple::OSType)ZigLLVM_Darwin == Triple::Darwin, "");
1018static_assert((Triple::OSType)ZigLLVM_DragonFly == Triple::DragonFly, "");
1019static_assert((Triple::OSType)ZigLLVM_FreeBSD == Triple::FreeBSD, "");
1020static_assert((Triple::OSType)ZigLLVM_Fuchsia == Triple::Fuchsia, "");
1021static_assert((Triple::OSType)ZigLLVM_IOS == Triple::IOS, "");
1022static_assert((Triple::OSType)ZigLLVM_KFreeBSD == Triple::KFreeBSD, "");
1023static_assert((Triple::OSType)ZigLLVM_Linux == Triple::Linux, "");
1024static_assert((Triple::OSType)ZigLLVM_Lv2 == Triple::Lv2, "");
1025static_assert((Triple::OSType)ZigLLVM_MacOSX == Triple::MacOSX, "");
1026static_assert((Triple::OSType)ZigLLVM_NetBSD == Triple::NetBSD, "");
1027static_assert((Triple::OSType)ZigLLVM_OpenBSD == Triple::OpenBSD, "");
1028static_assert((Triple::OSType)ZigLLVM_Solaris == Triple::Solaris, "");
1029static_assert((Triple::OSType)ZigLLVM_Win32 == Triple::Win32, "");
1030static_assert((Triple::OSType)ZigLLVM_Haiku == Triple::Haiku, "");
1031static_assert((Triple::OSType)ZigLLVM_Minix == Triple::Minix, "");
1032static_assert((Triple::OSType)ZigLLVM_RTEMS == Triple::RTEMS, "");
1033static_assert((Triple::OSType)ZigLLVM_NaCl == Triple::NaCl, "");
1034static_assert((Triple::OSType)ZigLLVM_CNK == Triple::CNK, "");
1035static_assert((Triple::OSType)ZigLLVM_AIX == Triple::AIX, "");
1036static_assert((Triple::OSType)ZigLLVM_CUDA == Triple::CUDA, "");
1037static_assert((Triple::OSType)ZigLLVM_NVCL == Triple::NVCL, "");
1038static_assert((Triple::OSType)ZigLLVM_AMDHSA == Triple::AMDHSA, "");
1039static_assert((Triple::OSType)ZigLLVM_PS4 == Triple::PS4, "");
1040static_assert((Triple::OSType)ZigLLVM_ELFIAMCU == Triple::ELFIAMCU, "");
1041static_assert((Triple::OSType)ZigLLVM_TvOS == Triple::TvOS, "");
1042static_assert((Triple::OSType)ZigLLVM_WatchOS == Triple::WatchOS, "");
1043static_assert((Triple::OSType)ZigLLVM_Mesa3D == Triple::Mesa3D, "");
1044static_assert((Triple::OSType)ZigLLVM_Contiki == Triple::Contiki, "");
1045static_assert((Triple::OSType)ZigLLVM_AMDPAL == Triple::AMDPAL, "");
1046static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, "");
1047
1048static_assert((Triple::EnvironmentType)ZigLLVM_UnknownEnvironment == Triple::UnknownEnvironment, "");
1049static_assert((Triple::EnvironmentType)ZigLLVM_GNU == Triple::GNU, "");
1050static_assert((Triple::EnvironmentType)ZigLLVM_GNUABIN32 == Triple::GNUABIN32, "");
1051static_assert((Triple::EnvironmentType)ZigLLVM_GNUABI64 == Triple::GNUABI64, "");
1052static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABI == Triple::GNUEABI, "");
1053static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABIHF == Triple::GNUEABIHF, "");
1054static_assert((Triple::EnvironmentType)ZigLLVM_GNUX32 == Triple::GNUX32, "");
1055static_assert((Triple::EnvironmentType)ZigLLVM_CODE16 == Triple::CODE16, "");
1056static_assert((Triple::EnvironmentType)ZigLLVM_EABI == Triple::EABI, "");
1057static_assert((Triple::EnvironmentType)ZigLLVM_EABIHF == Triple::EABIHF, "");
1058static_assert((Triple::EnvironmentType)ZigLLVM_Android == Triple::Android, "");
1059static_assert((Triple::EnvironmentType)ZigLLVM_Musl == Triple::Musl, "");
1060static_assert((Triple::EnvironmentType)ZigLLVM_MuslEABI == Triple::MuslEABI, "");
1061static_assert((Triple::EnvironmentType)ZigLLVM_MuslEABIHF == Triple::MuslEABIHF, "");
1062static_assert((Triple::EnvironmentType)ZigLLVM_MSVC == Triple::MSVC, "");
1063static_assert((Triple::EnvironmentType)ZigLLVM_Itanium == Triple::Itanium, "");
1064static_assert((Triple::EnvironmentType)ZigLLVM_Cygnus == Triple::Cygnus, "");
1065static_assert((Triple::EnvironmentType)ZigLLVM_CoreCLR == Triple::CoreCLR, "");
1066static_assert((Triple::EnvironmentType)ZigLLVM_Simulator == Triple::Simulator, "");
1067static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, "");
1068
1069static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, "");
1070static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, "");
1071static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, "");
1072static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, "");
1073static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");
std/array_list.zig+11
......@@ -398,3 +398,14 @@ test "std.ArrayList.insertSlice" {
398398 assert(list.len == 6);
399399 assert(list.items[0] == 1);
400400}
401
402const Item = struct {
403 integer: i32,
404 sub_items: ArrayList(Item),
405};
406
407test "std.ArrayList: ArrayList(T) of struct T" {
408 var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(debug.global_allocator) };
409 try root.sub_items.append( Item{ .integer = 42, .sub_items = ArrayList(Item).init(debug.global_allocator) } );
410 assert(root.sub_items.items[0].integer == 42);
411}
std/atomic/int.zig+4
......@@ -26,6 +26,10 @@ pub fn Int(comptime T: type) type {
2626 return @atomicLoad(T, &self.unprotected_value, AtomicOrder.SeqCst);
2727 }
2828
29 pub fn set(self: *Self, new_value: T) void {
30 _ = self.xchg(new_value);
31 }
32
2933 pub fn xchg(self: *Self, new_value: T) T {
3034 return @atomicRmw(T, &self.unprotected_value, builtin.AtomicRmwOp.Xchg, new_value, AtomicOrder.SeqCst);
3135 }
std/buf_map.zig+27-9
......@@ -16,7 +16,7 @@ pub const BufMap = struct {
1616 return self;
1717 }
1818
19 pub fn deinit(self: *const BufMap) void {
19 pub fn deinit(self: *BufMap) void {
2020 var it = self.hash_map.iterator();
2121 while (true) {
2222 const entry = it.next() orelse break;
......@@ -27,16 +27,34 @@ pub const BufMap = struct {
2727 self.hash_map.deinit();
2828 }
2929
30 /// Same as `set` but the key and value become owned by the BufMap rather
31 /// than being copied.
32 /// If `setMove` fails, the ownership of key and value does not transfer.
33 pub fn setMove(self: *BufMap, key: []u8, value: []u8) !void {
34 const get_or_put = try self.hash_map.getOrPut(key);
35 if (get_or_put.found_existing) {
36 self.free(get_or_put.kv.key);
37 get_or_put.kv.key = key;
38 }
39 get_or_put.kv.value = value;
40 }
41
42 /// `key` and `value` are copied into the BufMap.
3043 pub fn set(self: *BufMap, key: []const u8, value: []const u8) !void {
31 self.delete(key);
32 const key_copy = try self.copy(key);
33 errdefer self.free(key_copy);
3444 const value_copy = try self.copy(value);
3545 errdefer self.free(value_copy);
36 _ = try self.hash_map.put(key_copy, value_copy);
46 // Avoid copying key if it already exists
47 const get_or_put = try self.hash_map.getOrPut(key);
48 if (!get_or_put.found_existing) {
49 get_or_put.kv.key = self.copy(key) catch |err| {
50 _ = self.hash_map.remove(key);
51 return err;
52 };
53 }
54 get_or_put.kv.value = value_copy;
3755 }
3856
39 pub fn get(self: *const BufMap, key: []const u8) ?[]const u8 {
57 pub fn get(self: BufMap, key: []const u8) ?[]const u8 {
4058 const entry = self.hash_map.get(key) orelse return null;
4159 return entry.value;
4260 }
......@@ -47,7 +65,7 @@ pub const BufMap = struct {
4765 self.free(entry.value);
4866 }
4967
50 pub fn count(self: *const BufMap) usize {
68 pub fn count(self: BufMap) usize {
5169 return self.hash_map.count();
5270 }
5371
......@@ -55,11 +73,11 @@ pub const BufMap = struct {
5573 return self.hash_map.iterator();
5674 }
5775
58 fn free(self: *const BufMap, value: []const u8) void {
76 fn free(self: BufMap, value: []const u8) void {
5977 self.hash_map.allocator.free(value);
6078 }
6179
62 fn copy(self: *const BufMap, value: []const u8) ![]const u8 {
80 fn copy(self: BufMap, value: []const u8) ![]u8 {
6381 return mem.dupe(self.hash_map.allocator, u8, value);
6482 }
6583};
std/build.zig+38-8
......@@ -150,7 +150,11 @@ pub const Builder = struct {
150150 }
151151
152152 pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
153 return LibExeObjStep.createExecutable(self, name, root_src);
153 return LibExeObjStep.createExecutable(self, name, root_src, false);
154 }
155
156 pub fn addStaticExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
157 return LibExeObjStep.createExecutable(self, name, root_src, true);
154158 }
155159
156160 pub fn addObject(self: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
......@@ -795,11 +799,23 @@ pub const Target = union(enum) {
795799 };
796800 }
797801
802 pub fn isFreeBSD(self: *const Target) bool {
803 return switch (self.getOs()) {
804 builtin.Os.freebsd => true,
805 else => false,
806 };
807 }
808
798809 pub fn wantSharedLibSymLinks(self: *const Target) bool {
799810 return !self.isWindows();
800811 }
801812};
802813
814const Pkg = struct {
815 name: []const u8,
816 path: []const u8,
817};
818
803819pub const LibExeObjStep = struct {
804820 step: Step,
805821 builder: *Builder,
......@@ -842,11 +858,6 @@ pub const LibExeObjStep = struct {
842858 source_files: ArrayList([]const u8),
843859 object_src: []const u8,
844860
845 const Pkg = struct {
846 name: []const u8,
847 path: []const u8,
848 };
849
850861 const Kind = enum {
851862 Exe,
852863 Lib,
......@@ -884,8 +895,8 @@ pub const LibExeObjStep = struct {
884895 return self;
885896 }
886897
887 pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
888 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0))) catch unreachable;
898 pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {
899 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0))) catch unreachable;
889900 return self;
890901 }
891902
......@@ -1263,6 +1274,9 @@ pub const LibExeObjStep = struct {
12631274 zig_args.append("--ver-patch") catch unreachable;
12641275 zig_args.append(builder.fmt("{}", self.version.patch)) catch unreachable;
12651276 }
1277 if (self.kind == Kind.Exe and self.static) {
1278 zig_args.append("--static") catch unreachable;
1279 }
12661280
12671281 switch (self.target) {
12681282 Target.Native => {},
......@@ -1653,6 +1667,7 @@ pub const TestStep = struct {
16531667 exec_cmd_args: ?[]const ?[]const u8,
16541668 include_dirs: ArrayList([]const u8),
16551669 lib_paths: ArrayList([]const u8),
1670 packages: ArrayList(Pkg),
16561671 object_files: ArrayList([]const u8),
16571672 no_rosegment: bool,
16581673 output_path: ?[]const u8,
......@@ -1673,6 +1688,7 @@ pub const TestStep = struct {
16731688 .exec_cmd_args = null,
16741689 .include_dirs = ArrayList([]const u8).init(builder.allocator),
16751690 .lib_paths = ArrayList([]const u8).init(builder.allocator),
1691 .packages = ArrayList(Pkg).init(builder.allocator),
16761692 .object_files = ArrayList([]const u8).init(builder.allocator),
16771693 .no_rosegment = false,
16781694 .output_path = null,
......@@ -1688,6 +1704,13 @@ pub const TestStep = struct {
16881704 self.lib_paths.append(path) catch unreachable;
16891705 }
16901706
1707 pub fn addPackagePath(self: *TestStep, name: []const u8, pkg_index_path: []const u8) void {
1708 self.packages.append(Pkg{
1709 .name = name,
1710 .path = pkg_index_path,
1711 }) catch unreachable;
1712 }
1713
16911714 pub fn setVerbose(self: *TestStep, value: bool) void {
16921715 self.verbose = value;
16931716 }
......@@ -1864,6 +1887,13 @@ pub const TestStep = struct {
18641887 try zig_args.append(lib_path);
18651888 }
18661889
1890 for (self.packages.toSliceConst()) |pkg| {
1891 zig_args.append("--pkg-begin") catch unreachable;
1892 zig_args.append(pkg.name) catch unreachable;
1893 zig_args.append(builder.pathFromRoot(pkg.path)) catch unreachable;
1894 zig_args.append("--pkg-end") catch unreachable;
1895 }
1896
18671897 if (self.no_rosegment) {
18681898 try zig_args.append("--no-rosegment");
18691899 }
std/c/freebsd.zig created+33
......@@ -0,0 +1,33 @@
1const timespec = @import("../os/freebsd/index.zig").timespec;
2
3extern "c" fn __error() *c_int;
4pub const _errno = __error;
5
6pub extern "c" fn kqueue() c_int;
7pub extern "c" fn kevent(
8 kq: c_int,
9 changelist: [*]const Kevent,
10 nchanges: c_int,
11 eventlist: [*]Kevent,
12 nevents: c_int,
13 timeout: ?*const timespec,
14) c_int;
15pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
16pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
17pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
18
19/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
20pub const Kevent = extern struct {
21 ident: usize,
22 filter: i16,
23 flags: u16,
24 fflags: u32,
25 data: i64,
26 udata: usize,
27 // TODO ext
28};
29
30pub const pthread_attr_t = extern struct {
31 __size: [56]u8,
32 __align: c_long,
33};
std/c/index.zig+1
......@@ -5,6 +5,7 @@ pub use switch (builtin.os) {
55 Os.linux => @import("linux.zig"),
66 Os.windows => @import("windows.zig"),
77 Os.macosx, Os.ios => @import("darwin.zig"),
8 Os.freebsd => @import("freebsd.zig"),
89 else => empty_import,
910};
1011const empty_import = @import("../empty.zig");
std/coff.zig+22-22
......@@ -51,7 +51,7 @@ pub const Coff = struct {
5151
5252 // Seek to PE File Header (coff header)
5353 try self.in_file.seekTo(pe_pointer_offset);
54 const pe_magic_offset = try in.readIntLe(u32);
54 const pe_magic_offset = try in.readIntLittle(u32);
5555 try self.in_file.seekTo(pe_magic_offset);
5656
5757 var pe_header_magic: [4]u8 = undefined;
......@@ -60,13 +60,13 @@ pub const Coff = struct {
6060 return error.InvalidPEHeader;
6161
6262 self.coff_header = CoffHeader{
63 .machine = try in.readIntLe(u16),
64 .number_of_sections = try in.readIntLe(u16),
65 .timedate_stamp = try in.readIntLe(u32),
66 .pointer_to_symbol_table = try in.readIntLe(u32),
67 .number_of_symbols = try in.readIntLe(u32),
68 .size_of_optional_header = try in.readIntLe(u16),
69 .characteristics = try in.readIntLe(u16),
63 .machine = try in.readIntLittle(u16),
64 .number_of_sections = try in.readIntLittle(u16),
65 .timedate_stamp = try in.readIntLittle(u32),
66 .pointer_to_symbol_table = try in.readIntLittle(u32),
67 .number_of_symbols = try in.readIntLittle(u32),
68 .size_of_optional_header = try in.readIntLittle(u16),
69 .characteristics = try in.readIntLittle(u16),
7070 };
7171
7272 switch (self.coff_header.machine) {
......@@ -79,7 +79,7 @@ pub const Coff = struct {
7979
8080 fn loadOptionalHeader(self: *Coff, file_stream: *os.File.InStream) !void {
8181 const in = &file_stream.stream;
82 self.pe_header.magic = try in.readIntLe(u16);
82 self.pe_header.magic = try in.readIntLittle(u16);
8383 // For now we're only interested in finding the reference to the .pdb,
8484 // so we'll skip most of this header, which size is different in 32
8585 // 64 bits by the way.
......@@ -93,14 +93,14 @@ pub const Coff = struct {
9393
9494 try self.in_file.seekForward(skip_size);
9595
96 const number_of_rva_and_sizes = try in.readIntLe(u32);
96 const number_of_rva_and_sizes = try in.readIntLittle(u32);
9797 if (number_of_rva_and_sizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
9898 return error.InvalidPEHeader;
9999
100100 for (self.pe_header.data_directory) |*data_dir| {
101101 data_dir.* = OptionalHeader.DataDirectory{
102 .virtual_address = try in.readIntLe(u32),
103 .size = try in.readIntLe(u32),
102 .virtual_address = try in.readIntLittle(u32),
103 .size = try in.readIntLittle(u32),
104104 };
105105 }
106106 }
......@@ -124,7 +124,7 @@ pub const Coff = struct {
124124 if (!mem.eql(u8, cv_signature, "RSDS"))
125125 return error.InvalidPEMagic;
126126 try in.readNoEof(self.guid[0..]);
127 self.age = try in.readIntLe(u32);
127 self.age = try in.readIntLittle(u32);
128128
129129 // Finally read the null-terminated string.
130130 var byte = try in.readByte();
......@@ -157,15 +157,15 @@ pub const Coff = struct {
157157 try self.sections.append(Section{
158158 .header = SectionHeader{
159159 .name = name,
160 .misc = SectionHeader.Misc{ .physical_address = try in.readIntLe(u32) },
161 .virtual_address = try in.readIntLe(u32),
162 .size_of_raw_data = try in.readIntLe(u32),
163 .pointer_to_raw_data = try in.readIntLe(u32),
164 .pointer_to_relocations = try in.readIntLe(u32),
165 .pointer_to_line_numbers = try in.readIntLe(u32),
166 .number_of_relocations = try in.readIntLe(u16),
167 .number_of_line_numbers = try in.readIntLe(u16),
168 .characteristics = try in.readIntLe(u32),
160 .misc = SectionHeader.Misc{ .physical_address = try in.readIntLittle(u32) },
161 .virtual_address = try in.readIntLittle(u32),
162 .size_of_raw_data = try in.readIntLittle(u32),
163 .pointer_to_raw_data = try in.readIntLittle(u32),
164 .pointer_to_relocations = try in.readIntLittle(u32),
165 .pointer_to_line_numbers = try in.readIntLittle(u32),
166 .number_of_relocations = try in.readIntLittle(u16),
167 .number_of_line_numbers = try in.readIntLittle(u16),
168 .characteristics = try in.readIntLittle(u32),
169169 },
170170 });
171171 }
std/crypto/blake2.zig+7-4
......@@ -123,7 +123,8 @@ fn Blake2s(comptime out_len: usize) type {
123123 const rr = d.h[0 .. out_len / 32];
124124
125125 for (rr) |s, j| {
126 mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Little);
126 // TODO https://github.com/ziglang/zig/issues/863
127 mem.writeIntSliceLittle(u32, out[4 * j .. 4 * j + 4], s);
127128 }
128129 }
129130
......@@ -134,7 +135,8 @@ fn Blake2s(comptime out_len: usize) type {
134135 var v: [16]u32 = undefined;
135136
136137 for (m) |*r, i| {
137 r.* = mem.readIntLE(u32, b[4 * i .. 4 * i + 4]);
138 // TODO https://github.com/ziglang/zig/issues/863
139 r.* = mem.readIntSliceLittle(u32, b[4 * i .. 4 * i + 4]);
138140 }
139141
140142 var k: usize = 0;
......@@ -356,7 +358,8 @@ fn Blake2b(comptime out_len: usize) type {
356358 const rr = d.h[0 .. out_len / 64];
357359
358360 for (rr) |s, j| {
359 mem.writeInt(out[8 * j .. 8 * j + 8], s, builtin.Endian.Little);
361 // TODO https://github.com/ziglang/zig/issues/863
362 mem.writeIntSliceLittle(u64, out[8 * j .. 8 * j + 8], s);
360363 }
361364 }
362365
......@@ -367,7 +370,7 @@ fn Blake2b(comptime out_len: usize) type {
367370 var v: [16]u64 = undefined;
368371
369372 for (m) |*r, i| {
370 r.* = mem.readIntLE(u64, b[8 * i .. 8 * i + 8]);
373 r.* = mem.readIntSliceLittle(u64, b[8 * i .. 8 * i + 8]);
371374 }
372375
373376 var k: usize = 0;
std/crypto/chacha20.zig+27-26
......@@ -59,7 +59,8 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void {
5959 }
6060
6161 for (x) |_, i| {
62 mem.writeInt(out[4 * i .. 4 * i + 4], x[i] +% input[i], builtin.Endian.Little);
62 // TODO https://github.com/ziglang/zig/issues/863
63 mem.writeIntSliceLittle(u32, out[4 * i .. 4 * i + 4], x[i] +% input[i]);
6364 }
6465}
6566
......@@ -70,10 +71,10 @@ fn chaCha20_internal(out: []u8, in: []const u8, key: [8]u32, counter: [4]u32) vo
7071
7172 const c = "expand 32-byte k";
7273 const constant_le = []u32{
73 mem.readIntLE(u32, c[0..4]),
74 mem.readIntLE(u32, c[4..8]),
75 mem.readIntLE(u32, c[8..12]),
76 mem.readIntLE(u32, c[12..16]),
74 mem.readIntSliceLittle(u32, c[0..4]),
75 mem.readIntSliceLittle(u32, c[4..8]),
76 mem.readIntSliceLittle(u32, c[8..12]),
77 mem.readIntSliceLittle(u32, c[12..16]),
7778 };
7879
7980 mem.copy(u32, ctx[0..], constant_le[0..4]);
......@@ -117,19 +118,19 @@ pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce:
117118 var k: [8]u32 = undefined;
118119 var c: [4]u32 = undefined;
119120
120 k[0] = mem.readIntLE(u32, key[0..4]);
121 k[1] = mem.readIntLE(u32, key[4..8]);
122 k[2] = mem.readIntLE(u32, key[8..12]);
123 k[3] = mem.readIntLE(u32, key[12..16]);
124 k[4] = mem.readIntLE(u32, key[16..20]);
125 k[5] = mem.readIntLE(u32, key[20..24]);
126 k[6] = mem.readIntLE(u32, key[24..28]);
127 k[7] = mem.readIntLE(u32, key[28..32]);
121 k[0] = mem.readIntSliceLittle(u32, key[0..4]);
122 k[1] = mem.readIntSliceLittle(u32, key[4..8]);
123 k[2] = mem.readIntSliceLittle(u32, key[8..12]);
124 k[3] = mem.readIntSliceLittle(u32, key[12..16]);
125 k[4] = mem.readIntSliceLittle(u32, key[16..20]);
126 k[5] = mem.readIntSliceLittle(u32, key[20..24]);
127 k[6] = mem.readIntSliceLittle(u32, key[24..28]);
128 k[7] = mem.readIntSliceLittle(u32, key[28..32]);
128129
129130 c[0] = counter;
130 c[1] = mem.readIntLE(u32, nonce[0..4]);
131 c[2] = mem.readIntLE(u32, nonce[4..8]);
132 c[3] = mem.readIntLE(u32, nonce[8..12]);
131 c[1] = mem.readIntSliceLittle(u32, nonce[0..4]);
132 c[2] = mem.readIntSliceLittle(u32, nonce[4..8]);
133 c[3] = mem.readIntSliceLittle(u32, nonce[8..12]);
133134 chaCha20_internal(out, in, k, c);
134135}
135136
......@@ -144,19 +145,19 @@ pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]
144145 var k: [8]u32 = undefined;
145146 var c: [4]u32 = undefined;
146147
147 k[0] = mem.readIntLE(u32, key[0..4]);
148 k[1] = mem.readIntLE(u32, key[4..8]);
149 k[2] = mem.readIntLE(u32, key[8..12]);
150 k[3] = mem.readIntLE(u32, key[12..16]);
151 k[4] = mem.readIntLE(u32, key[16..20]);
152 k[5] = mem.readIntLE(u32, key[20..24]);
153 k[6] = mem.readIntLE(u32, key[24..28]);
154 k[7] = mem.readIntLE(u32, key[28..32]);
148 k[0] = mem.readIntSliceLittle(u32, key[0..4]);
149 k[1] = mem.readIntSliceLittle(u32, key[4..8]);
150 k[2] = mem.readIntSliceLittle(u32, key[8..12]);
151 k[3] = mem.readIntSliceLittle(u32, key[12..16]);
152 k[4] = mem.readIntSliceLittle(u32, key[16..20]);
153 k[5] = mem.readIntSliceLittle(u32, key[20..24]);
154 k[6] = mem.readIntSliceLittle(u32, key[24..28]);
155 k[7] = mem.readIntSliceLittle(u32, key[28..32]);
155156
156157 c[0] = @truncate(u32, counter);
157158 c[1] = @truncate(u32, counter >> 32);
158 c[2] = mem.readIntLE(u32, nonce[0..4]);
159 c[3] = mem.readIntLE(u32, nonce[4..8]);
159 c[2] = mem.readIntSliceLittle(u32, nonce[0..4]);
160 c[3] = mem.readIntSliceLittle(u32, nonce[4..8]);
160161
161162 const block_size = (1 << 6);
162163 const big_block = (block_size << 32);
std/crypto/md5.zig+2-1
......@@ -112,7 +112,8 @@ pub const Md5 = struct {
112112 d.round(d.buf[0..]);
113113
114114 for (d.s) |s, j| {
115 mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Little);
115 // TODO https://github.com/ziglang/zig/issues/863
116 mem.writeIntSliceLittle(u32, out[4 * j .. 4 * j + 4], s);
116117 }
117118 }
118119
std/crypto/poly1305.zig+14-13
......@@ -6,8 +6,8 @@ const std = @import("../index.zig");
66const builtin = @import("builtin");
77
88const Endian = builtin.Endian;
9const readInt = std.mem.readInt;
10const writeInt = std.mem.writeInt;
9const readIntSliceLittle = std.mem.readIntSliceLittle;
10const writeIntSliceLittle = std.mem.writeIntSliceLittle;
1111
1212pub const Poly1305 = struct {
1313 const Self = @This();
......@@ -59,19 +59,19 @@ pub const Poly1305 = struct {
5959 {
6060 var i: usize = 0;
6161 while (i < 1) : (i += 1) {
62 ctx.r[0] = readInt(key[0..4], u32, Endian.Little) & 0x0fffffff;
62 ctx.r[0] = readIntSliceLittle(u32, key[0..4]) & 0x0fffffff;
6363 }
6464 }
6565 {
6666 var i: usize = 1;
6767 while (i < 4) : (i += 1) {
68 ctx.r[i] = readInt(key[i * 4 .. i * 4 + 4], u32, Endian.Little) & 0x0ffffffc;
68 ctx.r[i] = readIntSliceLittle(u32, key[i * 4 .. i * 4 + 4]) & 0x0ffffffc;
6969 }
7070 }
7171 {
7272 var i: usize = 0;
7373 while (i < 4) : (i += 1) {
74 ctx.pad[i] = readInt(key[i * 4 + 16 .. i * 4 + 16 + 4], u32, Endian.Little);
74 ctx.pad[i] = readIntSliceLittle(u32, key[i * 4 + 16 .. i * 4 + 16 + 4]);
7575 }
7676 }
7777
......@@ -168,10 +168,10 @@ pub const Poly1305 = struct {
168168 const nb_blocks = nmsg.len >> 4;
169169 var i: usize = 0;
170170 while (i < nb_blocks) : (i += 1) {
171 ctx.c[0] = readInt(nmsg[0..4], u32, Endian.Little);
172 ctx.c[1] = readInt(nmsg[4..8], u32, Endian.Little);
173 ctx.c[2] = readInt(nmsg[8..12], u32, Endian.Little);
174 ctx.c[3] = readInt(nmsg[12..16], u32, Endian.Little);
171 ctx.c[0] = readIntSliceLittle(u32, nmsg[0..4]);
172 ctx.c[1] = readIntSliceLittle(u32, nmsg[4..8]);
173 ctx.c[2] = readIntSliceLittle(u32, nmsg[8..12]);
174 ctx.c[3] = readIntSliceLittle(u32, nmsg[12..16]);
175175 polyBlock(ctx);
176176 nmsg = nmsg[16..];
177177 }
......@@ -210,10 +210,11 @@ pub const Poly1305 = struct {
210210 const uu2 = (uu1 >> 32) + ctx.h[2] + ctx.pad[2]; // <= 2_00000000
211211 const uu3 = (uu2 >> 32) + ctx.h[3] + ctx.pad[3]; // <= 2_00000000
212212
213 writeInt(out[0..], @truncate(u32, uu0), Endian.Little);
214 writeInt(out[4..], @truncate(u32, uu1), Endian.Little);
215 writeInt(out[8..], @truncate(u32, uu2), Endian.Little);
216 writeInt(out[12..], @truncate(u32, uu3), Endian.Little);
213 // TODO https://github.com/ziglang/zig/issues/863
214 writeIntSliceLittle(u32, out[0..], @truncate(u32, uu0));
215 writeIntSliceLittle(u32, out[4..], @truncate(u32, uu1));
216 writeIntSliceLittle(u32, out[8..], @truncate(u32, uu2));
217 writeIntSliceLittle(u32, out[12..], @truncate(u32, uu3));
217218
218219 ctx.secureZero();
219220 }
std/crypto/sha1.zig+2-1
......@@ -109,7 +109,8 @@ pub const Sha1 = struct {
109109 d.round(d.buf[0..]);
110110
111111 for (d.s) |s, j| {
112 mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Big);
112 // TODO https://github.com/ziglang/zig/issues/863
113 mem.writeIntSliceBig(u32, out[4 * j .. 4 * j + 4], s);
113114 }
114115 }
115116
std/crypto/sha2.zig+4-2
......@@ -167,7 +167,8 @@ fn Sha2_32(comptime params: Sha2Params32) type {
167167 const rr = d.s[0 .. params.out_len / 32];
168168
169169 for (rr) |s, j| {
170 mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Big);
170 // TODO https://github.com/ziglang/zig/issues/863
171 mem.writeIntSliceBig(u32, out[4 * j .. 4 * j + 4], s);
171172 }
172173 }
173174
......@@ -508,7 +509,8 @@ fn Sha2_64(comptime params: Sha2Params64) type {
508509 const rr = d.s[0 .. params.out_len / 64];
509510
510511 for (rr) |s, j| {
511 mem.writeInt(out[8 * j .. 8 * j + 8], s, builtin.Endian.Big);
512 // TODO https://github.com/ziglang/zig/issues/863
513 mem.writeIntSliceBig(u64, out[8 * j .. 8 * j + 8], s);
512514 }
513515 }
514516
std/crypto/sha3.zig+3-2
......@@ -120,7 +120,7 @@ fn keccak_f(comptime F: usize, d: []u8) void {
120120 var c = []const u64{0} ** 5;
121121
122122 for (s) |*r, i| {
123 r.* = mem.readIntLE(u64, d[8 * i .. 8 * i + 8]);
123 r.* = mem.readIntSliceLittle(u64, d[8 * i .. 8 * i + 8]);
124124 }
125125
126126 comptime var x: usize = 0;
......@@ -167,7 +167,8 @@ fn keccak_f(comptime F: usize, d: []u8) void {
167167 }
168168
169169 for (s) |r, i| {
170 mem.writeInt(d[8 * i .. 8 * i + 8], r, builtin.Endian.Little);
170 // TODO https://github.com/ziglang/zig/issues/863
171 mem.writeIntSliceLittle(u64, d[8 * i .. 8 * i + 8], r);
171172 }
172173}
173174
std/crypto/x25519.zig+21-20
......@@ -7,8 +7,8 @@ const builtin = @import("builtin");
77const fmt = std.fmt;
88
99const Endian = builtin.Endian;
10const readInt = std.mem.readInt;
11const writeInt = std.mem.writeInt;
10const readIntSliceLittle = std.mem.readIntSliceLittle;
11const writeIntSliceLittle = std.mem.writeIntSliceLittle;
1212
1313// Based on Supercop's ref10 implementation.
1414pub const X25519 = struct {
......@@ -255,16 +255,16 @@ const Fe = struct {
255255
256256 var t: [10]i64 = undefined;
257257
258 t[0] = readInt(s[0..4], u32, Endian.Little);
259 t[1] = readInt(s[4..7], u32, Endian.Little) << 6;
260 t[2] = readInt(s[7..10], u32, Endian.Little) << 5;
261 t[3] = readInt(s[10..13], u32, Endian.Little) << 3;
262 t[4] = readInt(s[13..16], u32, Endian.Little) << 2;
263 t[5] = readInt(s[16..20], u32, Endian.Little);
264 t[6] = readInt(s[20..23], u32, Endian.Little) << 7;
265 t[7] = readInt(s[23..26], u32, Endian.Little) << 5;
266 t[8] = readInt(s[26..29], u32, Endian.Little) << 4;
267 t[9] = (readInt(s[29..32], u32, Endian.Little) & 0x7fffff) << 2;
258 t[0] = readIntSliceLittle(u32, s[0..4]);
259 t[1] = u32(readIntSliceLittle(u24, s[4..7])) << 6;
260 t[2] = u32(readIntSliceLittle(u24, s[7..10])) << 5;
261 t[3] = u32(readIntSliceLittle(u24, s[10..13])) << 3;
262 t[4] = u32(readIntSliceLittle(u24, s[13..16])) << 2;
263 t[5] = readIntSliceLittle(u32, s[16..20]);
264 t[6] = u32(readIntSliceLittle(u24, s[20..23])) << 7;
265 t[7] = u32(readIntSliceLittle(u24, s[23..26])) << 5;
266 t[8] = u32(readIntSliceLittle(u24, s[26..29])) << 4;
267 t[9] = (u32(readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2;
268268
269269 carry1(h, t[0..]);
270270 }
......@@ -544,14 +544,15 @@ const Fe = struct {
544544 ut[i] = @bitCast(u32, @intCast(i32, t[i]));
545545 }
546546
547 writeInt(s[0..], (ut[0] >> 0) | (ut[1] << 26), Endian.Little);
548 writeInt(s[4..], (ut[1] >> 6) | (ut[2] << 19), Endian.Little);
549 writeInt(s[8..], (ut[2] >> 13) | (ut[3] << 13), Endian.Little);
550 writeInt(s[12..], (ut[3] >> 19) | (ut[4] << 6), Endian.Little);
551 writeInt(s[16..], (ut[5] >> 0) | (ut[6] << 25), Endian.Little);
552 writeInt(s[20..], (ut[6] >> 7) | (ut[7] << 19), Endian.Little);
553 writeInt(s[24..], (ut[7] >> 13) | (ut[8] << 12), Endian.Little);
554 writeInt(s[28..], (ut[8] >> 20) | (ut[9] << 6), Endian.Little);
547 // TODO https://github.com/ziglang/zig/issues/863
548 writeIntSliceLittle(u32, s[0..4], (ut[0] >> 0) | (ut[1] << 26));
549 writeIntSliceLittle(u32, s[4..8], (ut[1] >> 6) | (ut[2] << 19));
550 writeIntSliceLittle(u32, s[8..12], (ut[2] >> 13) | (ut[3] << 13));
551 writeIntSliceLittle(u32, s[12..16], (ut[3] >> 19) | (ut[4] << 6));
552 writeIntSliceLittle(u32, s[16..20], (ut[5] >> 0) | (ut[6] << 25));
553 writeIntSliceLittle(u32, s[20..24], (ut[6] >> 7) | (ut[7] << 19));
554 writeIntSliceLittle(u32, s[24..28], (ut[7] >> 13) | (ut[8] << 12));
555 writeIntSliceLittle(u32, s[28..], (ut[8] >> 20) | (ut[9] << 6));
555556
556557 std.mem.secureZero(i64, t[0..]);
557558 }
std/debug/index.zig+261-238
......@@ -198,49 +198,44 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var,
198198 }
199199}
200200
201pub inline fn getReturnAddress(frame_count: usize) usize {
202 var fp = @ptrToInt(@frameAddress());
203 var i: usize = 0;
204 while (fp != 0 and i < frame_count) {
205 fp = @intToPtr(*const usize, fp).*;
206 i += 1;
201pub const StackIterator = struct {
202 first_addr: ?usize,
203 fp: usize,
204
205 pub fn init(first_addr: ?usize) StackIterator {
206 return StackIterator{
207 .first_addr = first_addr,
208 .fp = @ptrToInt(@frameAddress()),
209 };
207210 }
208 return @intToPtr(*const usize, fp + @sizeOf(usize)).*;
209}
211
212 fn next(self: *StackIterator) ?usize {
213 if (self.fp == 0) return null;
214 self.fp = @intToPtr(*const usize, self.fp).*;
215 if (self.fp == 0) return null;
216
217 if (self.first_addr) |addr| {
218 while (self.fp != 0) : (self.fp = @intToPtr(*const usize, self.fp).*) {
219 const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*;
220 if (addr == return_address) {
221 self.first_addr = null;
222 return return_address;
223 }
224 }
225 }
226
227 const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*;
228 return return_address;
229 }
230};
210231
211232pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
212233 switch (builtin.os) {
213234 builtin.Os.windows => return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr),
214235 else => {},
215236 }
216 const AddressState = union(enum) {
217 NotLookingForStartAddress,
218 LookingForStartAddress: usize,
219 };
220 // TODO: I want to express like this:
221 //var addr_state = if (start_addr) |addr| AddressState { .LookingForStartAddress = addr }
222 // else AddressState.NotLookingForStartAddress;
223 var addr_state: AddressState = undefined;
224 if (start_addr) |addr| {
225 addr_state = AddressState{ .LookingForStartAddress = addr };
226 } else {
227 addr_state = AddressState.NotLookingForStartAddress;
228 }
229
230 var fp = @ptrToInt(@frameAddress());
231 while (fp != 0) : (fp = @intToPtr(*const usize, fp).*) {
232 const return_address = @intToPtr(*const usize, fp + @sizeOf(usize)).*;
233
234 switch (addr_state) {
235 AddressState.NotLookingForStartAddress => {},
236 AddressState.LookingForStartAddress => |addr| {
237 if (return_address == addr) {
238 addr_state = AddressState.NotLookingForStartAddress;
239 } else {
240 continue;
241 }
242 },
243 }
237 var it = StackIterator.init(start_addr);
238 while (it.next()) |return_address| {
244239 try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
245240 }
246241}
......@@ -282,8 +277,9 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
282277
283278 var coff_section: *coff.Section = undefined;
284279 const mod_index = for (di.sect_contribs) |sect_contrib| {
285 if (sect_contrib.Section >= di.coff.sections.len) continue;
286 coff_section = &di.coff.sections.toSlice()[sect_contrib.Section];
280 if (sect_contrib.Section > di.coff.sections.len) continue;
281 // Remember that SectionContribEntry.Section is 1-based.
282 coff_section = &di.coff.sections.toSlice()[sect_contrib.Section - 1];
287283
288284 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
289285 const vaddr_end = vaddr_start + sect_contrib.Size;
......@@ -413,7 +409,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
413409
414410 if (opt_line_info) |line_info| {
415411 try out_stream.print("\n");
416 if (printLineFromFile(out_stream, line_info)) {
412 if (printLineFromFileAnyOs(out_stream, line_info)) {
417413 if (line_info.column == 0) {
418414 try out_stream.write("\n");
419415 } else {
......@@ -527,7 +523,7 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {
527523
528524 const modi = di.pdb.getStreamById(mod.mod_info.ModuleSymStream) orelse return error.MissingDebugInfo;
529525
530 const signature = try modi.stream.readIntLe(u32);
526 const signature = try modi.stream.readIntLittle(u32);
531527 if (signature != 4)
532528 return error.InvalidDebugInfo;
533529
......@@ -597,7 +593,15 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt
597593 } else "???";
598594 if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| {
599595 defer line_info.deinit();
600 try printLineInfo(di, out_stream, line_info, address, symbol_name, compile_unit_name, tty_color);
596 try printLineInfo(
597 out_stream,
598 line_info,
599 address,
600 symbol_name,
601 compile_unit_name,
602 tty_color,
603 printLineFromFileAnyOs,
604 );
601605 } else |err| switch (err) {
602606 error.MissingDebugInfo, error.InvalidDebugInfo => {
603607 if (tty_color) {
......@@ -610,7 +614,15 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt
610614 }
611615}
612616
613pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
617/// This function works in freestanding mode.
618/// fn printLineFromFile(out_stream: var, line_info: LineInfo) !void
619pub fn printSourceAtAddressDwarf(
620 debug_info: *DwarfInfo,
621 out_stream: var,
622 address: usize,
623 tty_color: bool,
624 comptime printLineFromFile: var,
625) !void {
614626 const compile_unit = findCompileUnit(debug_info, address) catch {
615627 if (tty_color) {
616628 try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n\n\n", address);
......@@ -620,10 +632,18 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres
620632 return;
621633 };
622634 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
623 if (getLineNumberInfoLinux(debug_info, compile_unit, address - 1)) |line_info| {
635 if (getLineNumberInfoDwarf(debug_info, compile_unit.*, address - 1)) |line_info| {
624636 defer line_info.deinit();
625637 const symbol_name = "???";
626 try printLineInfo(debug_info, out_stream, line_info, address, symbol_name, compile_unit_name, tty_color);
638 try printLineInfo(
639 out_stream,
640 line_info,
641 address,
642 symbol_name,
643 compile_unit_name,
644 tty_color,
645 printLineFromFile,
646 );
627647 } else |err| switch (err) {
628648 error.MissingDebugInfo, error.InvalidDebugInfo => {
629649 if (tty_color) {
......@@ -636,14 +656,18 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres
636656 }
637657}
638658
659pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
660 return printSourceAtAddressDwarf(debug_info, out_stream, address, tty_color, printLineFromFileAnyOs);
661}
662
639663fn printLineInfo(
640 debug_info: *DebugInfo,
641664 out_stream: var,
642665 line_info: LineInfo,
643666 address: usize,
644667 symbol_name: []const u8,
645668 compile_unit_name: []const u8,
646669 tty_color: bool,
670 comptime printLineFromFile: var,
647671) !void {
648672 if (tty_color) {
649673 try out_stream.print(
......@@ -733,9 +757,9 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
733757 try di.pdb.openFile(di.coff, path);
734758
735759 var pdb_stream = di.pdb.getStream(pdb.StreamType.Pdb) orelse return error.InvalidDebugInfo;
736 const version = try pdb_stream.stream.readIntLe(u32);
737 const signature = try pdb_stream.stream.readIntLe(u32);
738 const age = try pdb_stream.stream.readIntLe(u32);
760 const version = try pdb_stream.stream.readIntLittle(u32);
761 const signature = try pdb_stream.stream.readIntLittle(u32);
762 const age = try pdb_stream.stream.readIntLittle(u32);
739763 var guid: [16]u8 = undefined;
740764 try pdb_stream.stream.readNoEof(guid[0..]);
741765 if (!mem.eql(u8, di.coff.guid, guid) or di.coff.age != age)
......@@ -743,7 +767,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
743767 // We validated the executable and pdb match.
744768
745769 const string_table_index = str_tab_index: {
746 const name_bytes_len = try pdb_stream.stream.readIntLe(u32);
770 const name_bytes_len = try pdb_stream.stream.readIntLittle(u32);
747771 const name_bytes = try allocator.alloc(u8, name_bytes_len);
748772 try pdb_stream.stream.readNoEof(name_bytes);
749773
......@@ -773,8 +797,8 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
773797 };
774798 const bucket_list = try allocator.alloc(Bucket, present.len);
775799 for (present) |_| {
776 const name_offset = try pdb_stream.stream.readIntLe(u32);
777 const name_index = try pdb_stream.stream.readIntLe(u32);
800 const name_offset = try pdb_stream.stream.readIntLittle(u32);
801 const name_index = try pdb_stream.stream.readIntLittle(u32);
778802 const name = mem.toSlice(u8, name_bytes.ptr + name_offset);
779803 if (mem.eql(u8, name, "/names")) {
780804 break :str_tab_index name_index;
......@@ -835,7 +859,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
835859 var sect_contribs = ArrayList(pdb.SectionContribEntry).init(allocator);
836860 var sect_cont_offset: usize = 0;
837861 if (section_contrib_size != 0) {
838 const ver = @intToEnum(pdb.SectionContrSubstreamVersion, try dbi.stream.readIntLe(u32));
862 const ver = @intToEnum(pdb.SectionContrSubstreamVersion, try dbi.stream.readIntLittle(u32));
839863 if (ver != pdb.SectionContrSubstreamVersion.Ver60)
840864 return error.InvalidDebugInfo;
841865 sect_cont_offset += @sizeOf(u32);
......@@ -855,11 +879,11 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
855879}
856880
857881fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
858 const num_words = try stream.readIntLe(u32);
882 const num_words = try stream.readIntLittle(u32);
859883 var word_i: usize = 0;
860884 var list = ArrayList(usize).init(allocator);
861885 while (word_i != num_words) : (word_i += 1) {
862 const word = try stream.readIntLe(u32);
886 const word = try stream.readIntLittle(u32);
863887 var bit_i: u5 = 0;
864888 while (true) : (bit_i += 1) {
865889 if (word & (u32(1) << bit_i) != 0) {
......@@ -871,55 +895,68 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
871895 return list.toOwnedSlice();
872896}
873897
874fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DebugInfo {
875 var di = DebugInfo{
876 .self_exe_file = undefined,
877 .elf = undefined,
878 .debug_info = undefined,
879 .debug_abbrev = undefined,
880 .debug_str = undefined,
881 .debug_line = undefined,
882 .debug_ranges = null,
883 .abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator),
884 .compile_unit_list = ArrayList(CompileUnit).init(allocator),
898fn findDwarfSectionFromElf(elf_file: *elf.Elf, name: []const u8) !?DwarfInfo.Section {
899 const elf_header = (try elf_file.findSection(name)) orelse return null;
900 return DwarfInfo.Section{
901 .offset = elf_header.offset,
902 .size = elf_header.size,
885903 };
886 di.self_exe_file = try os.openSelfExe();
887 errdefer di.self_exe_file.close();
888
889 try di.elf.openFile(allocator, di.self_exe_file);
890 errdefer di.elf.close();
891
892 di.debug_info = (try di.elf.findSection(".debug_info")) orelse return error.MissingDebugInfo;
893 di.debug_abbrev = (try di.elf.findSection(".debug_abbrev")) orelse return error.MissingDebugInfo;
894 di.debug_str = (try di.elf.findSection(".debug_str")) orelse return error.MissingDebugInfo;
895 di.debug_line = (try di.elf.findSection(".debug_line")) orelse return error.MissingDebugInfo;
896 di.debug_ranges = (try di.elf.findSection(".debug_ranges"));
897 try scanAllCompileUnits(&di);
898 return di;
899904}
900905
901pub fn findElfSection(elf: *Elf, name: []const u8) ?*elf.Shdr {
902 var file_stream = elf.in_file.inStream();
903 const in = &file_stream.stream;
904
905 section_loop: for (elf.section_headers) |*elf_section| {
906 if (elf_section.sh_type == SHT_NULL) continue;
907
908 const name_offset = elf.string_section.offset + elf_section.name;
909 try elf.in_file.seekTo(name_offset);
910
911 for (name) |expected_c| {
912 const target_c = try in.readByte();
913 if (target_c == 0 or expected_c != target_c) continue :section_loop;
914 }
906/// Initialize DWARF info. The caller has the responsibility to initialize most
907/// the DwarfInfo fields before calling. These fields can be left undefined:
908/// * abbrev_table_list
909/// * compile_unit_list
910pub fn openDwarfDebugInfo(di: *DwarfInfo, allocator: *mem.Allocator) !void {
911 di.abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator);
912 di.compile_unit_list = ArrayList(CompileUnit).init(allocator);
913 try scanAllCompileUnits(di);
914}
915915
916 {
917 const null_byte = try in.readByte();
918 if (null_byte == 0) return elf_section;
919 }
920 }
916pub fn openElfDebugInfo(
917 allocator: *mem.Allocator,
918 elf_seekable_stream: *DwarfSeekableStream,
919 elf_in_stream: *DwarfInStream,
920) !DwarfInfo {
921 var efile: elf.Elf = undefined;
922 try efile.openStream(allocator, elf_seekable_stream, elf_in_stream);
923 errdefer efile.close();
924
925 var di = DwarfInfo{
926 .dwarf_seekable_stream = elf_seekable_stream,
927 .dwarf_in_stream = elf_in_stream,
928 .endian = efile.endian,
929 .debug_info = (try findDwarfSectionFromElf(&efile, ".debug_info")) orelse return error.MissingDebugInfo,
930 .debug_abbrev = (try findDwarfSectionFromElf(&efile, ".debug_abbrev")) orelse return error.MissingDebugInfo,
931 .debug_str = (try findDwarfSectionFromElf(&efile, ".debug_str")) orelse return error.MissingDebugInfo,
932 .debug_line = (try findDwarfSectionFromElf(&efile, ".debug_line")) orelse return error.MissingDebugInfo,
933 .debug_ranges = (try findDwarfSectionFromElf(&efile, ".debug_ranges")),
934 .abbrev_table_list = undefined,
935 .compile_unit_list = undefined,
936 };
937 try openDwarfDebugInfo(&di, allocator);
938 return di;
939}
921940
922 return null;
941fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DwarfInfo {
942 const S = struct {
943 var self_exe_file: os.File = undefined;
944 var self_exe_seekable_stream: os.File.SeekableStream = undefined;
945 var self_exe_in_stream: os.File.InStream = undefined;
946 };
947 S.self_exe_file = try os.openSelfExe();
948 errdefer S.self_exe_file.close();
949
950 S.self_exe_seekable_stream = S.self_exe_file.seekableStream();
951 S.self_exe_in_stream = S.self_exe_file.inStream();
952
953 return openElfDebugInfo(
954 allocator,
955 // TODO https://github.com/ziglang/zig/issues/764
956 @ptrCast(*DwarfSeekableStream, &S.self_exe_seekable_stream.stream),
957 // TODO https://github.com/ziglang/zig/issues/764
958 @ptrCast(*DwarfInStream, &S.self_exe_in_stream.stream),
959 );
923960}
924961
925962fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
......@@ -999,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
9991036 };
10001037}
10011038
1002fn printLineFromFile(out_stream: var, line_info: LineInfo) !void {
1039fn printLineFromFileAnyOs(out_stream: var, line_info: LineInfo) !void {
10031040 var f = try os.File.openRead(line_info.file_name);
10041041 defer f.close();
10051042 // TODO fstat and make sure that the file has the correct size
......@@ -1052,6 +1089,35 @@ const MachOFile = struct {
10521089 sect_debug_line: ?*const macho.section_64,
10531090};
10541091
1092pub const DwarfSeekableStream = io.SeekableStream(anyerror, anyerror);
1093pub const DwarfInStream = io.InStream(anyerror);
1094
1095pub const DwarfInfo = struct {
1096 dwarf_seekable_stream: *DwarfSeekableStream,
1097 dwarf_in_stream: *DwarfInStream,
1098 endian: builtin.Endian,
1099 debug_info: Section,
1100 debug_abbrev: Section,
1101 debug_str: Section,
1102 debug_line: Section,
1103 debug_ranges: ?Section,
1104 abbrev_table_list: ArrayList(AbbrevTableHeader),
1105 compile_unit_list: ArrayList(CompileUnit),
1106
1107 pub const Section = struct {
1108 offset: usize,
1109 size: usize,
1110 };
1111
1112 pub fn allocator(self: DwarfInfo) *mem.Allocator {
1113 return self.abbrev_table_list.allocator;
1114 }
1115
1116 pub fn readString(self: *DwarfInfo) ![]u8 {
1117 return readStringRaw(self.allocator(), self.dwarf_in_stream);
1118 }
1119};
1120
10551121pub const DebugInfo = switch (builtin.os) {
10561122 builtin.Os.macosx => struct {
10571123 symbols: []const MachoSymbol,
......@@ -1075,32 +1141,8 @@ pub const DebugInfo = switch (builtin.os) {
10751141 sect_contribs: []pdb.SectionContribEntry,
10761142 modules: []Module,
10771143 },
1078 builtin.Os.linux => struct {
1079 self_exe_file: os.File,
1080 elf: elf.Elf,
1081 debug_info: *elf.SectionHeader,
1082 debug_abbrev: *elf.SectionHeader,
1083 debug_str: *elf.SectionHeader,
1084 debug_line: *elf.SectionHeader,
1085 debug_ranges: ?*elf.SectionHeader,
1086 abbrev_table_list: ArrayList(AbbrevTableHeader),
1087 compile_unit_list: ArrayList(CompileUnit),
1088
1089 pub fn allocator(self: DebugInfo) *mem.Allocator {
1090 return self.abbrev_table_list.allocator;
1091 }
1092
1093 pub fn readString(self: *DebugInfo) ![]u8 {
1094 var in_file_stream = self.self_exe_file.inStream();
1095 const in_stream = &in_file_stream.stream;
1096 return readStringRaw(self.allocator(), in_stream);
1097 }
1098
1099 pub fn close(self: *DebugInfo) void {
1100 self.self_exe_file.close();
1101 self.elf.close();
1102 }
1103 },
1144 builtin.Os.linux => DwarfInfo,
1145 builtin.Os.freebsd => struct {},
11041146 else => @compileError("Unsupported OS"),
11051147};
11061148
......@@ -1158,7 +1200,7 @@ const Constant = struct {
11581200 fn asUnsignedLe(self: *const Constant) !u64 {
11591201 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;
11601202 if (self.signed) return error.InvalidDebugInfo;
1161 return mem.readInt(self.payload, u64, builtin.Endian.Little);
1203 return mem.readVarInt(u64, self.payload, builtin.Endian.Little);
11621204 }
11631205};
11641206
......@@ -1204,11 +1246,11 @@ const Die = struct {
12041246 };
12051247 }
12061248
1207 fn getAttrString(self: *const Die, st: *DebugInfo, id: u64) ![]u8 {
1249 fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]u8 {
12081250 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
12091251 return switch (form_value.*) {
12101252 FormValue.String => |value| value,
1211 FormValue.StrPtr => |offset| getString(st, offset),
1253 FormValue.StrPtr => |offset| getString(di, offset),
12121254 else => error.InvalidDebugInfo,
12131255 };
12141256 }
......@@ -1221,14 +1263,15 @@ const FileEntry = struct {
12211263 len_bytes: usize,
12221264};
12231265
1224const LineInfo = struct {
1266pub const LineInfo = struct {
12251267 line: usize,
12261268 column: usize,
1227 file_name: []u8,
1228 allocator: *mem.Allocator,
1269 file_name: []const u8,
1270 allocator: ?*mem.Allocator,
12291271
1230 fn deinit(self: *const LineInfo) void {
1231 self.allocator.free(self.file_name);
1272 fn deinit(self: LineInfo) void {
1273 const allocator = self.allocator orelse return;
1274 allocator.free(self.file_name);
12321275 }
12331276};
12341277
......@@ -1319,10 +1362,10 @@ fn readStringRaw(allocator: *mem.Allocator, in_stream: var) ![]u8 {
13191362 return buf.toSlice();
13201363}
13211364
1322fn getString(st: *DebugInfo, offset: u64) ![]u8 {
1323 const pos = st.debug_str.offset + offset;
1324 try st.self_exe_file.seekTo(pos);
1325 return st.readString();
1365fn getString(di: *DwarfInfo, offset: u64) ![]u8 {
1366 const pos = di.debug_str.offset + offset;
1367 try di.dwarf_seekable_stream.seekTo(pos);
1368 return di.readString();
13261369}
13271370
13281371fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
......@@ -1338,7 +1381,7 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
13381381}
13391382
13401383fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue {
1341 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
1384 const block_len = try in_stream.readVarInt(usize, builtin.Endian.Little, size);
13421385 return parseFormValueBlockLen(allocator, in_stream, block_len);
13431386}
13441387
......@@ -1352,11 +1395,11 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
13521395}
13531396
13541397fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
1355 return if (is_64) try in_stream.readIntLe(u64) else u64(try in_stream.readIntLe(u32));
1398 return if (is_64) try in_stream.readIntLittle(u64) else u64(try in_stream.readIntLittle(u32));
13561399}
13571400
13581401fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
1359 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) else unreachable;
1402 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable;
13601403}
13611404
13621405fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue {
......@@ -1365,18 +1408,11 @@ fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize)
13651408}
13661409
13671410fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue {
1368 const block_len = try in_stream.readIntLe(T);
1411 const block_len = try in_stream.readIntLittle(T);
13691412 return parseFormValueRefLen(allocator, in_stream, block_len);
13701413}
13711414
1372const ParseFormValueError = error{
1373 EndOfStream,
1374 InvalidDebugInfo,
1375 EndOfFile,
1376 OutOfMemory,
1377} || std.os.File.ReadError;
1378
1379fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) ParseFormValueError!FormValue {
1415fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue {
13801416 return switch (form_id) {
13811417 DW.FORM_addr => FormValue{ .Address = try parseFormValueTargetAddrSize(in_stream) },
13821418 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
......@@ -1414,7 +1450,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
14141450 },
14151451
14161452 DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
1417 DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLe(u64) },
1453 DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLittle(u64) },
14181454
14191455 DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) },
14201456 DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
......@@ -1426,25 +1462,22 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
14261462 };
14271463}
14281464
1429fn parseAbbrevTable(st: *DebugInfo) !AbbrevTable {
1430 const in_file = st.self_exe_file;
1431 var in_file_stream = in_file.inStream();
1432 const in_stream = &in_file_stream.stream;
1433 var result = AbbrevTable.init(st.allocator());
1465fn parseAbbrevTable(di: *DwarfInfo) !AbbrevTable {
1466 var result = AbbrevTable.init(di.allocator());
14341467 while (true) {
1435 const abbrev_code = try readULeb128(in_stream);
1468 const abbrev_code = try readULeb128(di.dwarf_in_stream);
14361469 if (abbrev_code == 0) return result;
14371470 try result.append(AbbrevTableEntry{
14381471 .abbrev_code = abbrev_code,
1439 .tag_id = try readULeb128(in_stream),
1440 .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,
1441 .attrs = ArrayList(AbbrevAttr).init(st.allocator()),
1472 .tag_id = try readULeb128(di.dwarf_in_stream),
1473 .has_children = (try di.dwarf_in_stream.readByte()) == DW.CHILDREN_yes,
1474 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),
14421475 });
14431476 const attrs = &result.items[result.len - 1].attrs;
14441477
14451478 while (true) {
1446 const attr_id = try readULeb128(in_stream);
1447 const form_id = try readULeb128(in_stream);
1479 const attr_id = try readULeb128(di.dwarf_in_stream);
1480 const form_id = try readULeb128(di.dwarf_in_stream);
14481481 if (attr_id == 0 and form_id == 0) break;
14491482 try attrs.append(AbbrevAttr{
14501483 .attr_id = attr_id,
......@@ -1456,18 +1489,18 @@ fn parseAbbrevTable(st: *DebugInfo) !AbbrevTable {
14561489
14571490/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
14581491/// seeks in the stream and parses it.
1459fn getAbbrevTable(st: *DebugInfo, abbrev_offset: u64) !*const AbbrevTable {
1460 for (st.abbrev_table_list.toSlice()) |*header| {
1492fn getAbbrevTable(di: *DwarfInfo, abbrev_offset: u64) !*const AbbrevTable {
1493 for (di.abbrev_table_list.toSlice()) |*header| {
14611494 if (header.offset == abbrev_offset) {
14621495 return &header.table;
14631496 }
14641497 }
1465 try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);
1466 try st.abbrev_table_list.append(AbbrevTableHeader{
1498 try di.dwarf_seekable_stream.seekTo(di.debug_abbrev.offset + abbrev_offset);
1499 try di.abbrev_table_list.append(AbbrevTableHeader{
14671500 .offset = abbrev_offset,
1468 .table = try parseAbbrevTable(st),
1501 .table = try parseAbbrevTable(di),
14691502 });
1470 return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;
1503 return &di.abbrev_table_list.items[di.abbrev_table_list.len - 1].table;
14711504}
14721505
14731506fn getAbbrevTableEntry(abbrev_table: *const AbbrevTable, abbrev_code: u64) ?*const AbbrevTableEntry {
......@@ -1477,23 +1510,20 @@ fn getAbbrevTableEntry(abbrev_table: *const AbbrevTable, abbrev_code: u64) ?*con
14771510 return null;
14781511}
14791512
1480fn parseDie(st: *DebugInfo, abbrev_table: *const AbbrevTable, is_64: bool) !Die {
1481 const in_file = st.self_exe_file;
1482 var in_file_stream = in_file.inStream();
1483 const in_stream = &in_file_stream.stream;
1484 const abbrev_code = try readULeb128(in_stream);
1513fn parseDie(di: *DwarfInfo, abbrev_table: *const AbbrevTable, is_64: bool) !Die {
1514 const abbrev_code = try readULeb128(di.dwarf_in_stream);
14851515 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) orelse return error.InvalidDebugInfo;
14861516
14871517 var result = Die{
14881518 .tag_id = table_entry.tag_id,
14891519 .has_children = table_entry.has_children,
1490 .attrs = ArrayList(Die.Attr).init(st.allocator()),
1520 .attrs = ArrayList(Die.Attr).init(di.allocator()),
14911521 };
14921522 try result.attrs.resize(table_entry.attrs.len);
14931523 for (table_entry.attrs.toSliceConst()) |attr, i| {
14941524 result.attrs.items[i] = Die.Attr{
14951525 .id = attr.attr_id,
1496 .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),
1526 .value = try parseFormValue(di.allocator(), di.dwarf_in_stream, attr.form_id, is_64),
14971527 };
14981528 }
14991529 return result;
......@@ -1697,22 +1727,18 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
16971727 return error.MissingDebugInfo;
16981728}
16991729
1700fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, target_address: usize) !LineInfo {
1730fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo {
17011731 const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir);
17021732
1703 const in_file = di.self_exe_file;
17041733 const debug_line_end = di.debug_line.offset + di.debug_line.size;
17051734 var this_offset = di.debug_line.offset;
17061735 var this_index: usize = 0;
17071736
1708 var in_file_stream = in_file.inStream();
1709 const in_stream = &in_file_stream.stream;
1710
17111737 while (this_offset < debug_line_end) : (this_index += 1) {
1712 try in_file.seekTo(this_offset);
1738 try di.dwarf_seekable_stream.seekTo(this_offset);
17131739
17141740 var is_64: bool = undefined;
1715 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
1741 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
17161742 if (unit_length == 0) return error.MissingDebugInfo;
17171743 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
17181744
......@@ -1721,35 +1747,35 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
17211747 continue;
17221748 }
17231749
1724 const version = try in_stream.readInt(di.elf.endian, u16);
1750 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
17251751 // TODO support 3 and 5
17261752 if (version != 2 and version != 4) return error.InvalidDebugInfo;
17271753
1728 const prologue_length = if (is_64) try in_stream.readInt(di.elf.endian, u64) else try in_stream.readInt(di.elf.endian, u32);
1729 const prog_start_offset = (try in_file.getPos()) + prologue_length;
1754 const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian);
1755 const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length;
17301756
1731 const minimum_instruction_length = try in_stream.readByte();
1757 const minimum_instruction_length = try di.dwarf_in_stream.readByte();
17321758 if (minimum_instruction_length == 0) return error.InvalidDebugInfo;
17331759
17341760 if (version >= 4) {
17351761 // maximum_operations_per_instruction
1736 _ = try in_stream.readByte();
1762 _ = try di.dwarf_in_stream.readByte();
17371763 }
17381764
1739 const default_is_stmt = (try in_stream.readByte()) != 0;
1740 const line_base = try in_stream.readByteSigned();
1765 const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0;
1766 const line_base = try di.dwarf_in_stream.readByteSigned();
17411767
1742 const line_range = try in_stream.readByte();
1768 const line_range = try di.dwarf_in_stream.readByte();
17431769 if (line_range == 0) return error.InvalidDebugInfo;
17441770
1745 const opcode_base = try in_stream.readByte();
1771 const opcode_base = try di.dwarf_in_stream.readByte();
17461772
17471773 const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1);
17481774
17491775 {
17501776 var i: usize = 0;
17511777 while (i < opcode_base - 1) : (i += 1) {
1752 standard_opcode_lengths[i] = try in_stream.readByte();
1778 standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte();
17531779 }
17541780 }
17551781
......@@ -1767,9 +1793,9 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
17671793 while (true) {
17681794 const file_name = try di.readString();
17691795 if (file_name.len == 0) break;
1770 const dir_index = try readULeb128(in_stream);
1771 const mtime = try readULeb128(in_stream);
1772 const len_bytes = try readULeb128(in_stream);
1796 const dir_index = try readULeb128(di.dwarf_in_stream);
1797 const mtime = try readULeb128(di.dwarf_in_stream);
1798 const len_bytes = try readULeb128(di.dwarf_in_stream);
17731799 try file_entries.append(FileEntry{
17741800 .file_name = file_name,
17751801 .dir_index = dir_index,
......@@ -1778,15 +1804,15 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
17781804 });
17791805 }
17801806
1781 try in_file.seekTo(prog_start_offset);
1807 try di.dwarf_seekable_stream.seekTo(prog_start_offset);
17821808
17831809 while (true) {
1784 const opcode = try in_stream.readByte();
1810 const opcode = try di.dwarf_in_stream.readByte();
17851811
17861812 if (opcode == DW.LNS_extended_op) {
1787 const op_size = try readULeb128(in_stream);
1813 const op_size = try readULeb128(di.dwarf_in_stream);
17881814 if (op_size < 1) return error.InvalidDebugInfo;
1789 var sub_op = try in_stream.readByte();
1815 var sub_op = try di.dwarf_in_stream.readByte();
17901816 switch (sub_op) {
17911817 DW.LNE_end_sequence => {
17921818 prog.end_sequence = true;
......@@ -1794,14 +1820,14 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
17941820 return error.MissingDebugInfo;
17951821 },
17961822 DW.LNE_set_address => {
1797 const addr = try in_stream.readInt(di.elf.endian, usize);
1823 const addr = try di.dwarf_in_stream.readInt(usize, di.endian);
17981824 prog.address = addr;
17991825 },
18001826 DW.LNE_define_file => {
18011827 const file_name = try di.readString();
1802 const dir_index = try readULeb128(in_stream);
1803 const mtime = try readULeb128(in_stream);
1804 const len_bytes = try readULeb128(in_stream);
1828 const dir_index = try readULeb128(di.dwarf_in_stream);
1829 const mtime = try readULeb128(di.dwarf_in_stream);
1830 const len_bytes = try readULeb128(di.dwarf_in_stream);
18051831 try file_entries.append(FileEntry{
18061832 .file_name = file_name,
18071833 .dir_index = dir_index,
......@@ -1811,7 +1837,7 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
18111837 },
18121838 else => {
18131839 const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo;
1814 try in_file.seekForward(fwd_amt);
1840 try di.dwarf_seekable_stream.seekForward(fwd_amt);
18151841 },
18161842 }
18171843 } else if (opcode >= opcode_base) {
......@@ -1830,19 +1856,19 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
18301856 prog.basic_block = false;
18311857 },
18321858 DW.LNS_advance_pc => {
1833 const arg = try readULeb128(in_stream);
1859 const arg = try readULeb128(di.dwarf_in_stream);
18341860 prog.address += arg * minimum_instruction_length;
18351861 },
18361862 DW.LNS_advance_line => {
1837 const arg = try readILeb128(in_stream);
1863 const arg = try readILeb128(di.dwarf_in_stream);
18381864 prog.line += arg;
18391865 },
18401866 DW.LNS_set_file => {
1841 const arg = try readULeb128(in_stream);
1867 const arg = try readULeb128(di.dwarf_in_stream);
18421868 prog.file = arg;
18431869 },
18441870 DW.LNS_set_column => {
1845 const arg = try readULeb128(in_stream);
1871 const arg = try readULeb128(di.dwarf_in_stream);
18461872 prog.column = arg;
18471873 },
18481874 DW.LNS_negate_stmt => {
......@@ -1856,14 +1882,14 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
18561882 prog.address += inc_addr;
18571883 },
18581884 DW.LNS_fixed_advance_pc => {
1859 const arg = try in_stream.readInt(di.elf.endian, u16);
1885 const arg = try di.dwarf_in_stream.readInt(u16, di.endian);
18601886 prog.address += arg;
18611887 },
18621888 DW.LNS_set_prologue_end => {},
18631889 else => {
18641890 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
18651891 const len_bytes = standard_opcode_lengths[opcode - 1];
1866 try in_file.seekForward(len_bytes);
1892 try di.dwarf_seekable_stream.seekForward(len_bytes);
18671893 },
18681894 }
18691895 }
......@@ -1875,36 +1901,33 @@ fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, targ
18751901 return error.MissingDebugInfo;
18761902}
18771903
1878fn scanAllCompileUnits(st: *DebugInfo) !void {
1879 const debug_info_end = st.debug_info.offset + st.debug_info.size;
1880 var this_unit_offset = st.debug_info.offset;
1904fn scanAllCompileUnits(di: *DwarfInfo) !void {
1905 const debug_info_end = di.debug_info.offset + di.debug_info.size;
1906 var this_unit_offset = di.debug_info.offset;
18811907 var cu_index: usize = 0;
18821908
1883 var in_file_stream = st.self_exe_file.inStream();
1884 const in_stream = &in_file_stream.stream;
1885
18861909 while (this_unit_offset < debug_info_end) {
1887 try st.self_exe_file.seekTo(this_unit_offset);
1910 try di.dwarf_seekable_stream.seekTo(this_unit_offset);
18881911
18891912 var is_64: bool = undefined;
1890 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
1913 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
18911914 if (unit_length == 0) return;
18921915 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
18931916
1894 const version = try in_stream.readInt(st.elf.endian, u16);
1917 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
18951918 if (version < 2 or version > 5) return error.InvalidDebugInfo;
18961919
1897 const debug_abbrev_offset = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32);
1920 const debug_abbrev_offset = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian);
18981921
1899 const address_size = try in_stream.readByte();
1922 const address_size = try di.dwarf_in_stream.readByte();
19001923 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
19011924
1902 const compile_unit_pos = try st.self_exe_file.getPos();
1903 const abbrev_table = try getAbbrevTable(st, debug_abbrev_offset);
1925 const compile_unit_pos = try di.dwarf_seekable_stream.getPos();
1926 const abbrev_table = try getAbbrevTable(di, debug_abbrev_offset);
19041927
1905 try st.self_exe_file.seekTo(compile_unit_pos);
1928 try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
19061929
1907 const compile_unit_die = try st.allocator().create(try parseDie(st, abbrev_table, is_64));
1930 const compile_unit_die = try di.allocator().create(try parseDie(di, abbrev_table, is_64));
19081931
19091932 if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
19101933
......@@ -1932,7 +1955,7 @@ fn scanAllCompileUnits(st: *DebugInfo) !void {
19321955 }
19331956 };
19341957
1935 try st.compile_unit_list.append(CompileUnit{
1958 try di.compile_unit_list.append(CompileUnit{
19361959 .version = version,
19371960 .is_64 = is_64,
19381961 .pc_range = pc_range,
......@@ -1945,20 +1968,18 @@ fn scanAllCompileUnits(st: *DebugInfo) !void {
19451968 }
19461969}
19471970
1948fn findCompileUnit(st: *DebugInfo, target_address: u64) !*const CompileUnit {
1949 var in_file_stream = st.self_exe_file.inStream();
1950 const in_stream = &in_file_stream.stream;
1951 for (st.compile_unit_list.toSlice()) |*compile_unit| {
1971fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
1972 for (di.compile_unit_list.toSlice()) |*compile_unit| {
19521973 if (compile_unit.pc_range) |range| {
19531974 if (target_address >= range.start and target_address < range.end) return compile_unit;
19541975 }
19551976 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
19561977 var base_address: usize = 0;
1957 if (st.debug_ranges) |debug_ranges| {
1958 try st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset);
1978 if (di.debug_ranges) |debug_ranges| {
1979 try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset);
19591980 while (true) {
1960 const begin_addr = try in_stream.readIntLe(usize);
1961 const end_addr = try in_stream.readIntLe(usize);
1981 const begin_addr = try di.dwarf_in_stream.readIntLittle(usize);
1982 const end_addr = try di.dwarf_in_stream.readIntLittle(usize);
19621983 if (begin_addr == 0 and end_addr == 0) {
19631984 break;
19641985 }
......@@ -1980,7 +2001,8 @@ fn findCompileUnit(st: *DebugInfo, target_address: u64) !*const CompileUnit {
19802001}
19812002
19822003fn readIntMem(ptr: *[*]const u8, comptime T: type, endian: builtin.Endian) T {
1983 const result = mem.readInt(ptr.*[0..@sizeOf(T)], T, endian);
2004 // TODO https://github.com/ziglang/zig/issues/863
2005 const result = mem.readIntSlice(T, ptr.*[0..@sizeOf(T)], endian);
19842006 ptr.* += @sizeOf(T);
19852007 return result;
19862008}
......@@ -1996,11 +2018,12 @@ fn readByteSignedMem(ptr: *[*]const u8) i8 {
19962018}
19972019
19982020fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {
1999 const first_32_bits = mem.readIntLE(u32, ptr.*[0..4]);
2021 // TODO this code can be improved with https://github.com/ziglang/zig/issues/863
2022 const first_32_bits = mem.readIntSliceLittle(u32, ptr.*[0..4]);
20002023 is_64.* = (first_32_bits == 0xffffffff);
20012024 if (is_64.*) {
20022025 ptr.* += 4;
2003 const result = mem.readIntLE(u64, ptr.*[0..8]);
2026 const result = mem.readIntSliceLittle(u64, ptr.*[0..8]);
20042027 ptr.* += 8;
20052028 return result;
20062029 } else {
......@@ -2063,10 +2086,10 @@ fn readILeb128Mem(ptr: *[*]const u8) !i64 {
20632086}
20642087
20652088fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool) !u64 {
2066 const first_32_bits = try in_stream.readIntLe(u32);
2089 const first_32_bits = try in_stream.readIntLittle(u32);
20672090 is_64.* = (first_32_bits == 0xffffffff);
20682091 if (is_64.*) {
2069 return in_stream.readIntLe(u64);
2092 return in_stream.readIntLittle(u64);
20702093 } else {
20712094 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
20722095 return u64(first_32_bits);
std/dynamic_library.zig+1-3
......@@ -19,7 +19,6 @@ pub const DynLib = switch (builtin.os) {
1919};
2020
2121pub const LinuxDynLib = struct {
22 allocator: *mem.Allocator,
2322 elf_lib: ElfLib,
2423 fd: i32,
2524 map_addr: usize,
......@@ -27,7 +26,7 @@ pub const LinuxDynLib = struct {
2726
2827 /// Trusts the file
2928 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
30 const fd = try std.os.posixOpen(allocator, path, 0, linux.O_RDONLY | linux.O_CLOEXEC);
29 const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC);
3130 errdefer std.os.close(fd);
3231
3332 const size = @intCast(usize, (try std.os.posixFStat(fd)).size);
......@@ -45,7 +44,6 @@ pub const LinuxDynLib = struct {
4544 const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size];
4645
4746 return DynLib{
48 .allocator = allocator,
4947 .elf_lib = try ElfLib.init(bytes),
5048 .fd = fd,
5149 .map_addr = addr,
std/elf.zig+59-56
......@@ -353,7 +353,8 @@ pub const SectionHeader = struct {
353353};
354354
355355pub const Elf = struct {
356 in_file: os.File,
356 seekable_stream: *io.SeekableStream(anyerror, anyerror),
357 in_stream: *io.InStream(anyerror),
357358 auto_close_stream: bool,
358359 is_64: bool,
359360 endian: builtin.Endian,
......@@ -370,19 +371,24 @@ pub const Elf = struct {
370371
371372 /// Call close when done.
372373 pub fn openPath(elf: *Elf, allocator: *mem.Allocator, path: []const u8) !void {
373 try elf.prealloc_file.open(path);
374 try elf.openFile(allocator, *elf.prealloc_file);
375 elf.auto_close_stream = true;
374 @compileError("TODO implement");
376375 }
377376
378377 /// Call close when done.
379378 pub fn openFile(elf: *Elf, allocator: *mem.Allocator, file: os.File) !void {
380 elf.allocator = allocator;
381 elf.in_file = file;
382 elf.auto_close_stream = false;
379 @compileError("TODO implement");
380 }
383381
384 var file_stream = elf.in_file.inStream();
385 const in = &file_stream.stream;
382 pub fn openStream(
383 elf: *Elf,
384 allocator: *mem.Allocator,
385 seekable_stream: *io.SeekableStream(anyerror, anyerror),
386 in: *io.InStream(anyerror),
387 ) !void {
388 elf.auto_close_stream = false;
389 elf.allocator = allocator;
390 elf.seekable_stream = seekable_stream;
391 elf.in_stream = in;
386392
387393 var magic: [4]u8 = undefined;
388394 try in.readNoEof(magic[0..]);
......@@ -404,9 +410,9 @@ pub const Elf = struct {
404410 if (version_byte != 1) return error.InvalidFormat;
405411
406412 // skip over padding
407 try elf.in_file.seekForward(9);
413 try seekable_stream.seekForward(9);
408414
409 elf.file_type = switch (try in.readInt(elf.endian, u16)) {
415 elf.file_type = switch (try in.readInt(u16, elf.endian)) {
410416 1 => FileType.Relocatable,
411417 2 => FileType.Executable,
412418 3 => FileType.Shared,
......@@ -414,7 +420,7 @@ pub const Elf = struct {
414420 else => return error.InvalidFormat,
415421 };
416422
417 elf.arch = switch (try in.readInt(elf.endian, u16)) {
423 elf.arch = switch (try in.readInt(u16, elf.endian)) {
418424 0x02 => Arch.Sparc,
419425 0x03 => Arch.x86,
420426 0x08 => Arch.Mips,
......@@ -427,32 +433,32 @@ pub const Elf = struct {
427433 else => return error.InvalidFormat,
428434 };
429435
430 const elf_version = try in.readInt(elf.endian, u32);
436 const elf_version = try in.readInt(u32, elf.endian);
431437 if (elf_version != 1) return error.InvalidFormat;
432438
433439 if (elf.is_64) {
434 elf.entry_addr = try in.readInt(elf.endian, u64);
435 elf.program_header_offset = try in.readInt(elf.endian, u64);
436 elf.section_header_offset = try in.readInt(elf.endian, u64);
440 elf.entry_addr = try in.readInt(u64, elf.endian);
441 elf.program_header_offset = try in.readInt(u64, elf.endian);
442 elf.section_header_offset = try in.readInt(u64, elf.endian);
437443 } else {
438 elf.entry_addr = u64(try in.readInt(elf.endian, u32));
439 elf.program_header_offset = u64(try in.readInt(elf.endian, u32));
440 elf.section_header_offset = u64(try in.readInt(elf.endian, u32));
444 elf.entry_addr = u64(try in.readInt(u32, elf.endian));
445 elf.program_header_offset = u64(try in.readInt(u32, elf.endian));
446 elf.section_header_offset = u64(try in.readInt(u32, elf.endian));
441447 }
442448
443449 // skip over flags
444 try elf.in_file.seekForward(4);
450 try seekable_stream.seekForward(4);
445451
446 const header_size = try in.readInt(elf.endian, u16);
452 const header_size = try in.readInt(u16, elf.endian);
447453 if ((elf.is_64 and header_size != 64) or (!elf.is_64 and header_size != 52)) {
448454 return error.InvalidFormat;
449455 }
450456
451 const ph_entry_size = try in.readInt(elf.endian, u16);
452 const ph_entry_count = try in.readInt(elf.endian, u16);
453 const sh_entry_size = try in.readInt(elf.endian, u16);
454 const sh_entry_count = try in.readInt(elf.endian, u16);
455 elf.string_section_index = u64(try in.readInt(elf.endian, u16));
457 const ph_entry_size = try in.readInt(u16, elf.endian);
458 const ph_entry_count = try in.readInt(u16, elf.endian);
459 const sh_entry_size = try in.readInt(u16, elf.endian);
460 const sh_entry_count = try in.readInt(u16, elf.endian);
461 elf.string_section_index = u64(try in.readInt(u16, elf.endian));
456462
457463 if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;
458464
......@@ -461,12 +467,12 @@ pub const Elf = struct {
461467 const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count);
462468 const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count);
463469
464 const stream_end = try elf.in_file.getEndPos();
470 const stream_end = try seekable_stream.getEndPos();
465471 if (stream_end < end_sh or stream_end < end_ph) {
466472 return error.InvalidFormat;
467473 }
468474
469 try elf.in_file.seekTo(elf.section_header_offset);
475 try seekable_stream.seekTo(elf.section_header_offset);
470476
471477 elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count);
472478 errdefer elf.allocator.free(elf.section_headers);
......@@ -475,32 +481,32 @@ pub const Elf = struct {
475481 if (sh_entry_size != 64) return error.InvalidFormat;
476482
477483 for (elf.section_headers) |*elf_section| {
478 elf_section.name = try in.readInt(elf.endian, u32);
479 elf_section.sh_type = try in.readInt(elf.endian, u32);
480 elf_section.flags = try in.readInt(elf.endian, u64);
481 elf_section.addr = try in.readInt(elf.endian, u64);
482 elf_section.offset = try in.readInt(elf.endian, u64);
483 elf_section.size = try in.readInt(elf.endian, u64);
484 elf_section.link = try in.readInt(elf.endian, u32);
485 elf_section.info = try in.readInt(elf.endian, u32);
486 elf_section.addr_align = try in.readInt(elf.endian, u64);
487 elf_section.ent_size = try in.readInt(elf.endian, u64);
484 elf_section.name = try in.readInt(u32, elf.endian);
485 elf_section.sh_type = try in.readInt(u32, elf.endian);
486 elf_section.flags = try in.readInt(u64, elf.endian);
487 elf_section.addr = try in.readInt(u64, elf.endian);
488 elf_section.offset = try in.readInt(u64, elf.endian);
489 elf_section.size = try in.readInt(u64, elf.endian);
490 elf_section.link = try in.readInt(u32, elf.endian);
491 elf_section.info = try in.readInt(u32, elf.endian);
492 elf_section.addr_align = try in.readInt(u64, elf.endian);
493 elf_section.ent_size = try in.readInt(u64, elf.endian);
488494 }
489495 } else {
490496 if (sh_entry_size != 40) return error.InvalidFormat;
491497
492498 for (elf.section_headers) |*elf_section| {
493499 // TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ?
494 elf_section.name = try in.readInt(elf.endian, u32);
495 elf_section.sh_type = try in.readInt(elf.endian, u32);
496 elf_section.flags = u64(try in.readInt(elf.endian, u32));
497 elf_section.addr = u64(try in.readInt(elf.endian, u32));
498 elf_section.offset = u64(try in.readInt(elf.endian, u32));
499 elf_section.size = u64(try in.readInt(elf.endian, u32));
500 elf_section.link = try in.readInt(elf.endian, u32);
501 elf_section.info = try in.readInt(elf.endian, u32);
502 elf_section.addr_align = u64(try in.readInt(elf.endian, u32));
503 elf_section.ent_size = u64(try in.readInt(elf.endian, u32));
500 elf_section.name = try in.readInt(u32, elf.endian);
501 elf_section.sh_type = try in.readInt(u32, elf.endian);
502 elf_section.flags = u64(try in.readInt(u32, elf.endian));
503 elf_section.addr = u64(try in.readInt(u32, elf.endian));
504 elf_section.offset = u64(try in.readInt(u32, elf.endian));
505 elf_section.size = u64(try in.readInt(u32, elf.endian));
506 elf_section.link = try in.readInt(u32, elf.endian);
507 elf_section.info = try in.readInt(u32, elf.endian);
508 elf_section.addr_align = u64(try in.readInt(u32, elf.endian));
509 elf_section.ent_size = u64(try in.readInt(u32, elf.endian));
504510 }
505511 }
506512
......@@ -521,26 +527,23 @@ pub const Elf = struct {
521527 pub fn close(elf: *Elf) void {
522528 elf.allocator.free(elf.section_headers);
523529
524 if (elf.auto_close_stream) elf.in_file.close();
530 if (elf.auto_close_stream) elf.prealloc_file.close();
525531 }
526532
527533 pub fn findSection(elf: *Elf, name: []const u8) !?*SectionHeader {
528 var file_stream = elf.in_file.inStream();
529 const in = &file_stream.stream;
530
531534 section_loop: for (elf.section_headers) |*elf_section| {
532535 if (elf_section.sh_type == SHT_NULL) continue;
533536
534537 const name_offset = elf.string_section.offset + elf_section.name;
535 try elf.in_file.seekTo(name_offset);
538 try elf.seekable_stream.seekTo(name_offset);
536539
537540 for (name) |expected_c| {
538 const target_c = try in.readByte();
541 const target_c = try elf.in_stream.readByte();
539542 if (target_c == 0 or expected_c != target_c) continue :section_loop;
540543 }
541544
542545 {
543 const null_byte = try in.readByte();
546 const null_byte = try elf.in_stream.readByte();
544547 if (null_byte == 0) return elf_section;
545548 }
546549 }
......@@ -549,7 +552,7 @@ pub const Elf = struct {
549552 }
550553
551554 pub fn seekToSection(elf: *Elf, elf_section: *SectionHeader) !void {
552 try elf.in_file.seekTo(elf_section.offset);
555 try elf.seekable_stream.seekTo(elf_section.offset);
553556 }
554557};
555558
std/event/fs.zig+21-10
......@@ -83,6 +83,7 @@ pub async fn pwritev(loop: *Loop, fd: os.FileHandle, data: []const []const u8, o
8383 switch (builtin.os) {
8484 builtin.Os.macosx,
8585 builtin.Os.linux,
86 builtin.Os.freebsd,
8687 => {
8788 const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len);
8889 defer loop.allocator.free(iovecs);
......@@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset:
219220 switch (builtin.os) {
220221 builtin.Os.macosx,
221222 builtin.Os.linux,
223 builtin.Os.freebsd,
222224 => {
223225 const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len);
224226 defer loop.allocator.free(iovecs);
......@@ -399,7 +401,7 @@ pub async fn openPosix(
399401
400402pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle {
401403 switch (builtin.os) {
402 builtin.Os.macosx, builtin.Os.linux => {
404 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
403405 const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC;
404406 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
405407 },
......@@ -427,6 +429,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os
427429 switch (builtin.os) {
428430 builtin.Os.macosx,
429431 builtin.Os.linux,
432 builtin.Os.freebsd,
430433 => {
431434 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;
432435 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
......@@ -449,7 +452,7 @@ pub async fn openReadWrite(
449452 mode: os.File.Mode,
450453) os.File.OpenError!os.FileHandle {
451454 switch (builtin.os) {
452 builtin.Os.macosx, builtin.Os.linux => {
455 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
453456 const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC;
454457 return await (async openPosix(loop, path, flags, mode) catch unreachable);
455458 },
......@@ -477,7 +480,7 @@ pub const CloseOperation = struct {
477480 os_data: OsData,
478481
479482 const OsData = switch (builtin.os) {
480 builtin.Os.linux, builtin.Os.macosx => OsDataPosix,
483 builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => OsDataPosix,
481484
482485 builtin.Os.windows => struct {
483486 handle: ?os.FileHandle,
......@@ -496,7 +499,7 @@ pub const CloseOperation = struct {
496499 self.* = CloseOperation{
497500 .loop = loop,
498501 .os_data = switch (builtin.os) {
499 builtin.Os.linux, builtin.Os.macosx => initOsDataPosix(self),
502 builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => initOsDataPosix(self),
500503 builtin.Os.windows => OsData{ .handle = null },
501504 else => @compileError("Unsupported OS"),
502505 },
......@@ -525,6 +528,7 @@ pub const CloseOperation = struct {
525528 switch (builtin.os) {
526529 builtin.Os.linux,
527530 builtin.Os.macosx,
531 builtin.Os.freebsd,
528532 => {
529533 if (self.os_data.have_fd) {
530534 self.loop.posixFsRequest(&self.os_data.close_req_node);
......@@ -546,6 +550,7 @@ pub const CloseOperation = struct {
546550 switch (builtin.os) {
547551 builtin.Os.linux,
548552 builtin.Os.macosx,
553 builtin.Os.freebsd,
549554 => {
550555 self.os_data.close_req_node.data.msg.Close.fd = handle;
551556 self.os_data.have_fd = true;
......@@ -562,6 +567,7 @@ pub const CloseOperation = struct {
562567 switch (builtin.os) {
563568 builtin.Os.linux,
564569 builtin.Os.macosx,
570 builtin.Os.freebsd,
565571 => {
566572 self.os_data.have_fd = false;
567573 },
......@@ -576,6 +582,7 @@ pub const CloseOperation = struct {
576582 switch (builtin.os) {
577583 builtin.Os.linux,
578584 builtin.Os.macosx,
585 builtin.Os.freebsd,
579586 => {
580587 assert(self.os_data.have_fd);
581588 return self.os_data.close_req_node.data.msg.Close.fd;
......@@ -599,6 +606,7 @@ pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8,
599606 switch (builtin.os) {
600607 builtin.Os.linux,
601608 builtin.Os.macosx,
609 builtin.Os.freebsd,
602610 => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable),
603611 builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable),
604612 else => @compileError("Unsupported OS"),
......@@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type {
704712 os_data: OsData,
705713
706714 const OsData = switch (builtin.os) {
707 builtin.Os.macosx => struct {
715 builtin.Os.macosx, builtin.Os.freebsd => struct {
708716 file_table: FileTable,
709717 table_lock: event.Lock,
710718
......@@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type {
793801 return self;
794802 },
795803
796 builtin.Os.macosx => {
804 builtin.Os.macosx, builtin.Os.freebsd => {
797805 const self = try loop.allocator.createOne(Self);
798806 errdefer loop.allocator.destroy(self);
799807
......@@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type {
813821 /// All addFile calls and removeFile calls must have completed.
814822 pub fn destroy(self: *Self) void {
815823 switch (builtin.os) {
816 builtin.Os.macosx => {
824 builtin.Os.macosx, builtin.Os.freebsd => {
817825 // TODO we need to cancel the coroutines before destroying the lock
818826 self.os_data.table_lock.deinit();
819827 var it = self.os_data.file_table.iterator();
......@@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type {
855863
856864 pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
857865 switch (builtin.os) {
858 builtin.Os.macosx => return await (async addFileMacosx(self, file_path, value) catch unreachable),
866 builtin.Os.macosx, builtin.Os.freebsd => return await (async addFileKEvent(self, file_path, value) catch unreachable),
859867 builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable),
860868 builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable),
861869 else => @compileError("Unsupported OS"),
862870 }
863871 }
864872
865 async fn addFileMacosx(self: *Self, file_path: []const u8, value: V) !?V {
873 async fn addFileKEvent(self: *Self, file_path: []const u8, value: V) !?V {
866874 const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path);
867875 var resolved_path_consumed = false;
868876 defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);
......@@ -871,7 +879,10 @@ pub fn Watch(comptime V: type) type {
871879 var close_op_consumed = false;
872880 defer if (!close_op_consumed) close_op.finish();
873881
874 const flags = posix.O_SYMLINK | posix.O_EVTONLY;
882 const flags = switch (builtin.os) {
883 builtin.Os.macosx => posix.O_SYMLINK | posix.O_EVTONLY,
884 else => 0,
885 };
875886 const mode = 0;
876887 const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);
877888 close_op.setHandle(fd);
std/event/io.zig+9-5
......@@ -39,18 +39,22 @@ pub fn InStream(comptime ReadError: type) type {
3939 if (amt_read < buf.len) return error.EndOfStream;
4040 }
4141
42 pub async fn readIntLe(self: *Self, comptime T: type) !T {
43 return await (async self.readInt(builtin.Endian.Little, T) catch unreachable);
42 pub async fn readIntLittle(self: *Self, comptime T: type) !T {
43 var bytes: [@sizeOf(T)]u8 = undefined;
44 try await (async self.readNoEof(bytes[0..]) catch unreachable);
45 return mem.readIntLittle(T, &bytes);
4446 }
4547
4648 pub async fn readIntBe(self: *Self, comptime T: type) !T {
47 return await (async self.readInt(builtin.Endian.Big, T) catch unreachable);
49 var bytes: [@sizeOf(T)]u8 = undefined;
50 try await (async self.readNoEof(bytes[0..]) catch unreachable);
51 return mem.readIntBig(T, &bytes);
4852 }
4953
50 pub async fn readInt(self: *Self, endian: builtin.Endian, comptime T: type) !T {
54 pub async fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {
5155 var bytes: [@sizeOf(T)]u8 = undefined;
5256 try await (async self.readNoEof(bytes[0..]) catch unreachable);
53 return mem.readInt(bytes, T, endian);
57 return mem.readInt(T, &bytes, endian);
5458 }
5559
5660 pub async fn readStruct(self: *Self, comptime T: type) !T {
std/event/loop.zig+14-13
......@@ -49,7 +49,7 @@ pub const Loop = struct {
4949 };
5050
5151 pub const EventFd = switch (builtin.os) {
52 builtin.Os.macosx => MacOsEventFd,
52 builtin.Os.macosx, builtin.Os.freebsd => KEventFd,
5353 builtin.Os.linux => struct {
5454 base: ResumeNode,
5555 epoll_op: u32,
......@@ -62,13 +62,13 @@ pub const Loop = struct {
6262 else => @compileError("unsupported OS"),
6363 };
6464
65 const MacOsEventFd = struct {
65 const KEventFd = struct {
6666 base: ResumeNode,
6767 kevent: posix.Kevent,
6868 };
6969
7070 pub const Basic = switch (builtin.os) {
71 builtin.Os.macosx => MacOsBasic,
71 builtin.Os.macosx, builtin.Os.freebsd => KEventBasic,
7272 builtin.Os.linux => struct {
7373 base: ResumeNode,
7474 },
......@@ -78,7 +78,7 @@ pub const Loop = struct {
7878 else => @compileError("unsupported OS"),
7979 };
8080
81 const MacOsBasic = struct {
81 const KEventBasic = struct {
8282 base: ResumeNode,
8383 kev: posix.Kevent,
8484 };
......@@ -214,7 +214,7 @@ pub const Loop = struct {
214214 self.extra_threads[extra_thread_index] = try os.spawnThread(self, workerRun);
215215 }
216216 },
217 builtin.Os.macosx => {
217 builtin.Os.macosx, builtin.Os.freebsd => {
218218 self.os_data.kqfd = try os.bsdKQueue();
219219 errdefer os.close(self.os_data.kqfd);
220220
......@@ -369,7 +369,7 @@ pub const Loop = struct {
369369 os.close(self.os_data.epollfd);
370370 self.allocator.free(self.eventfd_resume_nodes);
371371 },
372 builtin.Os.macosx => {
372 builtin.Os.macosx, builtin.Os.freebsd => {
373373 os.close(self.os_data.kqfd);
374374 os.close(self.os_data.fs_kqfd);
375375 },
......@@ -484,7 +484,7 @@ pub const Loop = struct {
484484 const eventfd_node = &resume_stack_node.data;
485485 eventfd_node.base.handle = next_tick_node.data;
486486 switch (builtin.os) {
487 builtin.Os.macosx => {
487 builtin.Os.macosx, builtin.Os.freebsd => {
488488 const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent);
489489 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
490490 _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
......@@ -546,6 +546,7 @@ pub const Loop = struct {
546546 switch (builtin.os) {
547547 builtin.Os.linux,
548548 builtin.Os.macosx,
549 builtin.Os.freebsd,
549550 => self.os_data.fs_thread.wait(),
550551 else => {},
551552 }
......@@ -610,7 +611,7 @@ pub const Loop = struct {
610611 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
611612 return;
612613 },
613 builtin.Os.macosx => {
614 builtin.Os.macosx, builtin.Os.freebsd => {
614615 self.posixFsRequest(&self.os_data.fs_end_request);
615616 const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent);
616617 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
......@@ -668,7 +669,7 @@ pub const Loop = struct {
668669 }
669670 }
670671 },
671 builtin.Os.macosx => {
672 builtin.Os.macosx, builtin.Os.freebsd => {
672673 var eventlist: [1]posix.Kevent = undefined;
673674 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
674675 const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
......@@ -731,7 +732,7 @@ pub const Loop = struct {
731732 self.beginOneEvent(); // finished in posixFsRun after processing the msg
732733 self.os_data.fs_queue.put(request_node);
733734 switch (builtin.os) {
734 builtin.Os.macosx => {
735 builtin.Os.macosx, builtin.Os.freebsd => {
735736 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake);
736737 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
737738 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
......@@ -801,7 +802,7 @@ pub const Loop = struct {
801802 else => unreachable,
802803 }
803804 },
804 builtin.Os.macosx => {
805 builtin.Os.macosx, builtin.Os.freebsd => {
805806 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait);
806807 var out_kevs: [1]posix.Kevent = undefined;
807808 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
......@@ -813,7 +814,7 @@ pub const Loop = struct {
813814
814815 const OsData = switch (builtin.os) {
815816 builtin.Os.linux => LinuxOsData,
816 builtin.Os.macosx => MacOsData,
817 builtin.Os.macosx, builtin.Os.freebsd => KEventData,
817818 builtin.Os.windows => struct {
818819 io_port: windows.HANDLE,
819820 extra_thread_count: usize,
......@@ -821,7 +822,7 @@ pub const Loop = struct {
821822 else => struct {},
822823 };
823824
824 const MacOsData = struct {
825 const KEventData = struct {
825826 kqfd: i32,
826827 final_kevent: posix.Kevent,
827828 fs_kevent_wake: posix.Kevent,
std/fmt/index.zig+72-8
......@@ -2,6 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const debug = std.debug;
44const assert = debug.assert;
5const assertError = debug.assertError;
56const mem = std.mem;
67const builtin = @import("builtin");
78const errol = @import("errol/index.zig");
......@@ -116,7 +117,7 @@ pub fn formatType(
116117 return output(context, @errorName(value));
117118 }
118119 switch (@typeInfo(T)) {
119 builtin.TypeId.Int, builtin.TypeId.Float => {
120 builtin.TypeId.ComptimeInt, builtin.TypeId.Int, builtin.TypeId.Float => {
120121 return formatValue(value, fmt, context, Errors, output);
121122 },
122123 builtin.TypeId.Void => {
......@@ -242,6 +243,9 @@ pub fn formatType(
242243 }
243244 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
244245 },
246 builtin.TypeId.Fn => {
247 return format(context, Errors, output, "{}@{x}", @typeName(T), @ptrToInt(value));
248 },
245249 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
246250 }
247251}
......@@ -267,11 +271,15 @@ fn formatValue(
267271 }
268272 }
269273
270 comptime var T = @typeOf(value);
274 const T = @typeOf(value);
271275 switch (@typeId(T)) {
272276 builtin.TypeId.Float => return formatFloatValue(value, fmt, context, Errors, output),
273277 builtin.TypeId.Int => return formatIntValue(value, fmt, context, Errors, output),
274 else => unreachable,
278 builtin.TypeId.ComptimeInt => {
279 const Int = math.IntFittingRange(value, value);
280 return formatIntValue(Int(value), fmt, context, Errors, output);
281 },
282 else => comptime unreachable,
275283 }
276284}
277285
......@@ -288,9 +296,10 @@ pub fn formatIntValue(
288296 if (fmt.len > 0) {
289297 switch (fmt[0]) {
290298 'c' => {
291 if (@typeOf(value) == u8) {
292 if (fmt.len > 1) @compileError("Unknown format character: " ++ []u8{fmt[1]});
293 return formatAsciiChar(value, context, Errors, output);
299 if (@typeOf(value).bit_count <= 8) {
300 if (fmt.len > 1)
301 @compileError("Unknown format character: " ++ []u8{fmt[1]});
302 return formatAsciiChar(u8(value), context, Errors, output);
294303 }
295304 },
296305 'b' => {
......@@ -811,13 +820,41 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
811820
812821 for (buf) |c| {
813822 const digit = try charToDigit(c, radix);
814 x = try math.mul(T, x, radix);
815 x = try math.add(T, x, digit);
823
824 if (x != 0) x = try math.mul(T, x, try math.cast(T, radix));
825 x = try math.add(T, x, try math.cast(T, digit));
816826 }
817827
818828 return x;
819829}
820830
831test "parseUnsigned" {
832 assert((try parseUnsigned(u16, "050124", 10)) == 50124);
833 assert((try parseUnsigned(u16, "65535", 10)) == 65535);
834 assertError(parseUnsigned(u16, "65536", 10), error.Overflow);
835
836 assert((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
837 assertError(parseUnsigned(u64, "10000000000000000", 16), error.Overflow);
838
839 assert((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
840
841 assert((try parseUnsigned(u7, "1", 10)) == 1);
842 assert((try parseUnsigned(u7, "1000", 2)) == 8);
843
844 assertError(parseUnsigned(u32, "f", 10), error.InvalidCharacter);
845 assertError(parseUnsigned(u8, "109", 8), error.InvalidCharacter);
846
847 assert((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
848
849 // these numbers should fit even though the radix itself doesn't fit in the destination type
850 assert((try parseUnsigned(u1, "0", 10)) == 0);
851 assert((try parseUnsigned(u1, "1", 10)) == 1);
852 assertError(parseUnsigned(u1, "2", 10), error.Overflow);
853 assert((try parseUnsigned(u1, "001", 16)) == 1);
854 assert((try parseUnsigned(u2, "3", 16)) == 3);
855 assertError(parseUnsigned(u2, "4", 16), error.Overflow);
856}
857
821858pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
822859 const value = switch (c) {
823860 '0'...'9' => c - '0',
......@@ -935,6 +972,25 @@ test "fmt.format" {
935972 const value: u8 = 0b1100;
936973 try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", value);
937974 }
975 {
976 var buf1: [32]u8 = undefined;
977 var context = BufPrintContext{ .remaining = buf1[0..] };
978 try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite);
979 var res = buf1[0 .. buf1.len - context.remaining.len];
980 assert(mem.eql(u8, res, "1234"));
981
982 context = BufPrintContext{ .remaining = buf1[0..] };
983 try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite);
984 res = buf1[0 .. buf1.len - context.remaining.len];
985 debug.warn("{}\n", res);
986 assert(mem.eql(u8, res, "a"));
987
988 context = BufPrintContext{ .remaining = buf1[0..] };
989 try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite);
990 res = buf1[0 .. buf1.len - context.remaining.len];
991 debug.warn("{}\n", res);
992 assert(mem.eql(u8, res, "1100"));
993 }
938994 {
939995 const value: [3]u8 = "abc";
940996 try testFmt("array: abc\n", "array: {}\n", value);
......@@ -956,6 +1012,14 @@ test "fmt.format" {
9561012 try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value);
9571013 try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", value);
9581014 }
1015 {
1016 const value = @intToPtr(fn () void, 0xdeadbeef);
1017 try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value);
1018 }
1019 {
1020 const value = @intToPtr(fn () void, 0xdeadbeef);
1021 try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value);
1022 }
9591023 try testFmt("buf: Test \n", "buf: {s5}\n", "Test");
9601024 try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test");
9611025 try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C");
std/hash/siphash.zig+7-7
......@@ -42,8 +42,8 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
4242 pub fn init(key: []const u8) Self {
4343 debug.assert(key.len >= 16);
4444
45 const k0 = mem.readInt(key[0..8], u64, Endian.Little);
46 const k1 = mem.readInt(key[8..16], u64, Endian.Little);
45 const k0 = mem.readIntSliceLittle(u64, key[0..8]);
46 const k1 = mem.readIntSliceLittle(u64, key[8..16]);
4747
4848 var d = Self{
4949 .v0 = k0 ^ 0x736f6d6570736575,
......@@ -121,7 +121,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
121121 fn round(d: *Self, b: []const u8) void {
122122 debug.assert(b.len == 8);
123123
124 const m = mem.readInt(b[0..], u64, Endian.Little);
124 const m = mem.readIntSliceLittle(u64, b[0..]);
125125 d.v3 ^= m;
126126
127127 comptime var i: usize = 0;
......@@ -162,7 +162,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
162162const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
163163
164164test "siphash64-2-4 sanity" {
165 const vectors = [][]const u8{
165 const vectors = [][8]u8{
166166 "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // ""
167167 "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00"
168168 "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc
......@@ -235,13 +235,13 @@ test "siphash64-2-4 sanity" {
235235 for (vectors) |vector, i| {
236236 buffer[i] = @intCast(u8, i);
237237
238 const expected = mem.readInt(vector, u64, Endian.Little);
238 const expected = mem.readIntLittle(u64, &vector);
239239 debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
240240 }
241241}
242242
243243test "siphash128-2-4 sanity" {
244 const vectors = [][]const u8{
244 const vectors = [][16]u8{
245245 "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93",
246246 "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45",
247247 "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4",
......@@ -314,7 +314,7 @@ test "siphash128-2-4 sanity" {
314314 for (vectors) |vector, i| {
315315 buffer[i] = @intCast(u8, i);
316316
317 const expected = mem.readInt(vector, u128, Endian.Little);
317 const expected = mem.readIntLittle(u128, &vector);
318318 debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
319319 }
320320}
std/hash_map.zig+14
......@@ -126,6 +126,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
126126 };
127127 }
128128
129 pub fn getOrPutValue(self: *Self, key: K, value: V) !*KV {
130 const res = try self.getOrPut(key);
131 if (!res.found_existing)
132 res.kv.value = value;
133
134 return res.kv;
135 }
136
129137 fn ensureCapacity(self: *Self) !void {
130138 if (self.entries.len == 0) {
131139 return self.initCapacity(16);
......@@ -354,6 +362,12 @@ test "basic hash map usage" {
354362 gop2.kv.value = 42;
355363 assert(map.get(99).?.value == 42);
356364
365 const gop3 = try map.getOrPutValue(5, 5);
366 assert(gop3.value == 77);
367
368 const gop4 = try map.getOrPutValue(100, 41);
369 assert(gop4.value == 41);
370
357371 assert(map.contains(2));
358372 assert(map.get(2).?.value == 22);
359373 _ = map.remove(2);
std/heap.zig+4-4
......@@ -66,11 +66,11 @@ pub const DirectAllocator = struct {
6666 }
6767 }
6868
69 fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 {
69 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
7070 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
7171
7272 switch (builtin.os) {
73 Os.linux, Os.macosx, Os.ios => {
73 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
7474 const p = os.posix;
7575 const alloc_size = if (alignment <= os.page_size) n else n + alignment;
7676 const addr = p.mmap(null, alloc_size, p.PROT_READ | p.PROT_WRITE, p.MAP_PRIVATE | p.MAP_ANONYMOUS, -1, 0);
......@@ -121,7 +121,7 @@ pub const DirectAllocator = struct {
121121 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
122122
123123 switch (builtin.os) {
124 Os.linux, Os.macosx, Os.ios => {
124 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
125125 if (new_size <= old_mem.len) {
126126 const base_addr = @ptrToInt(old_mem.ptr);
127127 const old_addr_end = base_addr + old_mem.len;
......@@ -166,7 +166,7 @@ pub const DirectAllocator = struct {
166166 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
167167
168168 switch (builtin.os) {
169 Os.linux, Os.macosx, Os.ios => {
169 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
170170 _ = os.posix.munmap(@ptrToInt(bytes.ptr), bytes.len);
171171 },
172172 Os.windows => {
std/index.zig+2-1
......@@ -57,7 +57,8 @@ test "std" {
5757 _ = @import("mutex.zig");
5858 _ = @import("segmented_list.zig");
5959 _ = @import("spinlock.zig");
60
60
61 _ = @import("dynamic_library.zig");
6162 _ = @import("base64.zig");
6263 _ = @import("build.zig");
6364 _ = @import("c/index.zig");
std/io.zig+104-37
......@@ -32,6 +32,8 @@ pub fn getStdIn() GetStdIoErrs!File {
3232 return File.openHandle(handle);
3333}
3434
35pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;
36
3537pub fn InStream(comptime ReadError: type) type {
3638 return struct {
3739 const Self = @This();
......@@ -150,35 +152,43 @@ pub fn InStream(comptime ReadError: type) type {
150152 }
151153
152154 /// Reads a native-endian integer
153 pub fn readIntNe(self: *Self, comptime T: type) !T {
154 return self.readInt(builtin.endian, T);
155 pub fn readIntNative(self: *Self, comptime T: type) !T {
156 var bytes: [@sizeOf(T)]u8 = undefined;
157 try self.readNoEof(bytes[0..]);
158 return mem.readIntNative(T, &bytes);
159 }
160
161 /// Reads a foreign-endian integer
162 pub fn readIntForeign(self: *Self, comptime T: type) !T {
163 var bytes: [@sizeOf(T)]u8 = undefined;
164 try self.readNoEof(bytes[0..]);
165 return mem.readIntForeign(T, &bytes);
155166 }
156167
157 pub fn readIntLe(self: *Self, comptime T: type) !T {
168 pub fn readIntLittle(self: *Self, comptime T: type) !T {
158169 var bytes: [@sizeOf(T)]u8 = undefined;
159170 try self.readNoEof(bytes[0..]);
160 return mem.readIntLE(T, bytes);
171 return mem.readIntLittle(T, &bytes);
161172 }
162173
163 pub fn readIntBe(self: *Self, comptime T: type) !T {
174 pub fn readIntBig(self: *Self, comptime T: type) !T {
164175 var bytes: [@sizeOf(T)]u8 = undefined;
165176 try self.readNoEof(bytes[0..]);
166 return mem.readIntBE(T, bytes);
177 return mem.readIntBig(T, &bytes);
167178 }
168179
169 pub fn readInt(self: *Self, endian: builtin.Endian, comptime T: type) !T {
180 pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {
170181 var bytes: [@sizeOf(T)]u8 = undefined;
171182 try self.readNoEof(bytes[0..]);
172 return mem.readInt(bytes, T, endian);
183 return mem.readInt(T, &bytes, endian);
173184 }
174185
175 pub fn readVarInt(self: *Self, endian: builtin.Endian, comptime T: type, size: usize) !T {
176 assert(size <= @sizeOf(T));
177 assert(size <= 8);
178 var input_buf: [8]u8 = undefined;
179 const input_slice = input_buf[0..size];
180 try self.readNoEof(input_slice);
181 return mem.readInt(input_slice, T, endian);
186 pub fn readVarInt(self: *Self, comptime ReturnType: type, endian: builtin.Endian, size: usize) !ReturnType {
187 assert(size <= @sizeOf(ReturnType));
188 var bytes_buf: [@sizeOf(ReturnType)]u8 = undefined;
189 const bytes = bytes_buf[0..size];
190 try self.readNoEof(bytes);
191 return mem.readVarInt(ReturnType, bytes, endian);
182192 }
183193
184194 pub fn skipBytes(self: *Self, num_bytes: usize) !void {
......@@ -227,25 +237,34 @@ pub fn OutStream(comptime WriteError: type) type {
227237 }
228238
229239 /// Write a native-endian integer.
230 pub fn writeIntNe(self: *Self, comptime T: type, value: T) Error!void {
231 return self.writeInt(builtin.endian, T, value);
240 pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void {
241 var bytes: [@sizeOf(T)]u8 = undefined;
242 mem.writeIntNative(T, &bytes, value);
243 return self.writeFn(self, bytes);
244 }
245
246 /// Write a foreign-endian integer.
247 pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void {
248 var bytes: [@sizeOf(T)]u8 = undefined;
249 mem.writeIntForeign(T, &bytes, value);
250 return self.writeFn(self, bytes);
232251 }
233252
234 pub fn writeIntLe(self: *Self, comptime T: type, value: T) Error!void {
253 pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void {
235254 var bytes: [@sizeOf(T)]u8 = undefined;
236 mem.writeIntLE(T, &bytes, value);
255 mem.writeIntLittle(T, &bytes, value);
237256 return self.writeFn(self, bytes);
238257 }
239258
240 pub fn writeIntBe(self: *Self, comptime T: type, value: T) Error!void {
259 pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void {
241260 var bytes: [@sizeOf(T)]u8 = undefined;
242 mem.writeIntBE(T, &bytes, value);
261 mem.writeIntBig(T, &bytes, value);
243262 return self.writeFn(self, bytes);
244263 }
245264
246 pub fn writeInt(self: *Self, endian: builtin.Endian, comptime T: type, value: T) Error!void {
265 pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void {
247266 var bytes: [@sizeOf(T)]u8 = undefined;
248 mem.writeInt(bytes[0..], value, endian);
267 mem.writeInt(T, &bytes, value, endian);
249268 return self.writeFn(self, bytes);
250269 }
251270 };
......@@ -683,25 +702,73 @@ test "import io tests" {
683702 }
684703}
685704
686pub fn readLine(buf: []u8) !usize {
687 var stdin = getStdIn() catch return error.StdInUnavailable;
688 var adapter = stdin.inStream();
689 var stream = &adapter.stream;
690 var index: usize = 0;
705pub fn readLine(buf: *std.Buffer) ![]u8 {
706 var stdin = try getStdIn();
707 var stdin_stream = stdin.inStream();
708 return readLineFrom(&stdin_stream.stream, buf);
709}
710
711/// Reads all characters until the next newline into buf, and returns
712/// a slice of the characters read (excluding the newline character(s)).
713pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
714 const start = buf.len();
691715 while (true) {
692 const byte = stream.readByte() catch return error.EndOfFile;
716 const byte = try stream.readByte();
693717 switch (byte) {
694718 '\r' => {
695719 // trash the following \n
696 _ = stream.readByte() catch return error.EndOfFile;
697 return index;
698 },
699 '\n' => return index,
700 else => {
701 if (index == buf.len) return error.InputTooLong;
702 buf[index] = byte;
703 index += 1;
720 _ = try stream.readByte();
721 return buf.toSlice()[start..];
704722 },
723 '\n' => return buf.toSlice()[start..],
724 else => try buf.appendByte(byte),
705725 }
706726 }
707727}
728
729test "io.readLineFrom" {
730 var bytes: [128]u8 = undefined;
731 const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
732
733 var buf = try std.Buffer.initSize(allocator, 0);
734 var mem_stream = SliceInStream.init(
735 \\Line 1
736 \\Line 22
737 \\Line 333
738 );
739 const stream = &mem_stream.stream;
740
741 debug.assert(mem.eql(u8, "Line 1", try readLineFrom(stream, &buf)));
742 debug.assert(mem.eql(u8, "Line 22", try readLineFrom(stream, &buf)));
743 debug.assertError(readLineFrom(stream, &buf), error.EndOfStream);
744 debug.assert(mem.eql(u8, buf.toSlice(), "Line 1Line 22Line 333"));
745}
746
747pub fn readLineSlice(slice: []u8) ![]u8 {
748 var stdin = try getStdIn();
749 var stdin_stream = stdin.inStream();
750 return readLineSliceFrom(&stdin_stream.stream, slice);
751}
752
753/// Reads all characters until the next newline into slice, and returns
754/// a slice of the characters read (excluding the newline character(s)).
755pub fn readLineSliceFrom(stream: var, slice: []u8) ![]u8 {
756 // We cannot use Buffer.fromOwnedSlice, as it wants to append a null byte
757 // after taking ownership, which would always require an allocation.
758 var buf = std.Buffer{ .list = std.ArrayList(u8).fromOwnedSlice(debug.failing_allocator, slice) };
759 try buf.resize(0);
760 return try readLineFrom(stream, &buf);
761}
762
763test "io.readLineSliceFrom" {
764 var buf: [7]u8 = undefined;
765 var mem_stream = SliceInStream.init(
766 \\Line 1
767 \\Line 22
768 \\Line 333
769 );
770 const stream = &mem_stream.stream;
771
772 debug.assert(mem.eql(u8, "Line 1", try readLineSliceFrom(stream, buf[0..])));
773 debug.assertError(readLineSliceFrom(stream, buf[0..]), error.OutOfMemory);
774}
std/io/seekable_stream.zig created+32
......@@ -0,0 +1,32 @@
1const std = @import("../index.zig");
2const InStream = std.io.InStream;
3
4pub fn SeekableStream(comptime SeekErrorType: type, comptime GetSeekPosErrorType: type) type {
5 return struct {
6 const Self = @This();
7 pub const SeekError = SeekErrorType;
8 pub const GetSeekPosError = GetSeekPosErrorType;
9
10 seekToFn: fn (self: *Self, pos: usize) SeekError!void,
11 seekForwardFn: fn (self: *Self, pos: isize) SeekError!void,
12
13 getPosFn: fn (self: *Self) GetSeekPosError!usize,
14 getEndPosFn: fn (self: *Self) GetSeekPosError!usize,
15
16 pub fn seekTo(self: *Self, pos: usize) SeekError!void {
17 return self.seekToFn(self, pos);
18 }
19
20 pub fn seekForward(self: *Self, amt: isize) SeekError!void {
21 return self.seekForwardFn(self, amt);
22 }
23
24 pub fn getEndPos(self: *Self) GetSeekPosError!usize {
25 return self.getEndPosFn(self);
26 }
27
28 pub fn getPos(self: *Self) GetSeekPosError!usize {
29 return self.getPosFn(self);
30 }
31 };
32}
std/json.zig+17-10
......@@ -910,7 +910,7 @@ fn checkNext(p: *TokenStream, id: Token.Id) void {
910910 debug.assert(token.id == id);
911911}
912912
913test "token" {
913test "json.token" {
914914 const s =
915915 \\{
916916 \\ "Image": {
......@@ -980,7 +980,7 @@ pub fn validate(s: []const u8) bool {
980980 return p.complete;
981981}
982982
983test "json validate" {
983test "json.validate" {
984984 debug.assert(validate("{}"));
985985}
986986
......@@ -1188,7 +1188,7 @@ pub const Parser = struct {
11881188 }
11891189
11901190 var value = p.stack.pop();
1191 try p.pushToParent(value);
1191 try p.pushToParent(&value);
11921192 },
11931193 Token.Id.String => {
11941194 try p.stack.append(try p.parseString(allocator, token, input, i));
......@@ -1251,7 +1251,7 @@ pub const Parser = struct {
12511251 }
12521252
12531253 var value = p.stack.pop();
1254 try p.pushToParent(value);
1254 try p.pushToParent(&value);
12551255 },
12561256 Token.Id.ObjectBegin => {
12571257 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
......@@ -1312,19 +1312,19 @@ pub const Parser = struct {
13121312 }
13131313 }
13141314
1315 fn pushToParent(p: *Parser, value: Value) !void {
1316 switch (p.stack.at(p.stack.len - 1)) {
1315 fn pushToParent(p: *Parser, value: *const Value) !void {
1316 switch (p.stack.toSlice()[p.stack.len - 1]) {
13171317 // Object Parent -> [ ..., object, <key>, value ]
13181318 Value.String => |key| {
13191319 _ = p.stack.pop();
13201320
13211321 var object = &p.stack.items[p.stack.len - 1].Object;
1322 _ = try object.put(key, value);
1322 _ = try object.put(key, value.*);
13231323 p.state = State.ObjectKey;
13241324 },
13251325 // Array Parent -> [ ..., <array>, value ]
13261326 Value.Array => |*array| {
1327 try array.append(value);
1327 try array.append(value.*);
13281328 p.state = State.ArrayValue;
13291329 },
13301330 else => {
......@@ -1348,7 +1348,7 @@ pub const Parser = struct {
13481348 }
13491349};
13501350
1351test "json parser dynamic" {
1351test "json.parser.dynamic" {
13521352 var p = Parser.init(debug.global_allocator, false);
13531353 defer p.deinit();
13541354
......@@ -1364,7 +1364,8 @@ test "json parser dynamic" {
13641364 \\ "Width": 100
13651365 \\ },
13661366 \\ "Animated" : false,
1367 \\ "IDs": [116, 943, 234, 38793]
1367 \\ "IDs": [116, 943, 234, 38793],
1368 \\ "ArrayOfObject": [{"n": "m"}]
13681369 \\ }
13691370 \\}
13701371 ;
......@@ -1387,4 +1388,10 @@ test "json parser dynamic" {
13871388
13881389 const animated = image.Object.get("Animated").?.value;
13891390 debug.assert(animated.Bool == false);
1391
1392 const array_of_object = image.Object.get("ArrayOfObject").?.value;
1393 debug.assert(array_of_object.Array.len == 1);
1394
1395 const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;
1396 debug.assert(mem.eql(u8, obj0.String, "m"));
13901397}
std/json_test.zig+319-319
......@@ -21,7 +21,7 @@ fn any(comptime s: []const u8) void {
2121//
2222// Additional tests not part of test JSONTestSuite.
2323
24test "y_trailing_comma_after_empty" {
24test "json.test.y_trailing_comma_after_empty" {
2525 ok(
2626 \\{"1":[],"2":{},"3":"4"}
2727 );
......@@ -29,252 +29,252 @@ test "y_trailing_comma_after_empty" {
2929
3030////////////////////////////////////////////////////////////////////////////////////////////////////
3131
32test "y_array_arraysWithSpaces" {
32test "json.test.y_array_arraysWithSpaces" {
3333 ok(
3434 \\[[] ]
3535 );
3636}
3737
38test "y_array_empty" {
38test "json.test.y_array_empty" {
3939 ok(
4040 \\[]
4141 );
4242}
4343
44test "y_array_empty-string" {
44test "json.test.y_array_empty-string" {
4545 ok(
4646 \\[""]
4747 );
4848}
4949
50test "y_array_ending_with_newline" {
50test "json.test.y_array_ending_with_newline" {
5151 ok(
5252 \\["a"]
5353 );
5454}
5555
56test "y_array_false" {
56test "json.test.y_array_false" {
5757 ok(
5858 \\[false]
5959 );
6060}
6161
62test "y_array_heterogeneous" {
62test "json.test.y_array_heterogeneous" {
6363 ok(
6464 \\[null, 1, "1", {}]
6565 );
6666}
6767
68test "y_array_null" {
68test "json.test.y_array_null" {
6969 ok(
7070 \\[null]
7171 );
7272}
7373
74test "y_array_with_1_and_newline" {
74test "json.test.y_array_with_1_and_newline" {
7575 ok(
7676 \\[1
7777 \\]
7878 );
7979}
8080
81test "y_array_with_leading_space" {
81test "json.test.y_array_with_leading_space" {
8282 ok(
8383 \\ [1]
8484 );
8585}
8686
87test "y_array_with_several_null" {
87test "json.test.y_array_with_several_null" {
8888 ok(
8989 \\[1,null,null,null,2]
9090 );
9191}
9292
93test "y_array_with_trailing_space" {
93test "json.test.y_array_with_trailing_space" {
9494 ok("[2] ");
9595}
9696
97test "y_number_0e+1" {
97test "json.test.y_number_0e+1" {
9898 ok(
9999 \\[0e+1]
100100 );
101101}
102102
103test "y_number_0e1" {
103test "json.test.y_number_0e1" {
104104 ok(
105105 \\[0e1]
106106 );
107107}
108108
109test "y_number_after_space" {
109test "json.test.y_number_after_space" {
110110 ok(
111111 \\[ 4]
112112 );
113113}
114114
115test "y_number_double_close_to_zero" {
115test "json.test.y_number_double_close_to_zero" {
116116 ok(
117117 \\[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]
118118 );
119119}
120120
121test "y_number_int_with_exp" {
121test "json.test.y_number_int_with_exp" {
122122 ok(
123123 \\[20e1]
124124 );
125125}
126126
127test "y_number" {
127test "json.test.y_number" {
128128 ok(
129129 \\[123e65]
130130 );
131131}
132132
133test "y_number_minus_zero" {
133test "json.test.y_number_minus_zero" {
134134 ok(
135135 \\[-0]
136136 );
137137}
138138
139test "y_number_negative_int" {
139test "json.test.y_number_negative_int" {
140140 ok(
141141 \\[-123]
142142 );
143143}
144144
145test "y_number_negative_one" {
145test "json.test.y_number_negative_one" {
146146 ok(
147147 \\[-1]
148148 );
149149}
150150
151test "y_number_negative_zero" {
151test "json.test.y_number_negative_zero" {
152152 ok(
153153 \\[-0]
154154 );
155155}
156156
157test "y_number_real_capital_e" {
157test "json.test.y_number_real_capital_e" {
158158 ok(
159159 \\[1E22]
160160 );
161161}
162162
163test "y_number_real_capital_e_neg_exp" {
163test "json.test.y_number_real_capital_e_neg_exp" {
164164 ok(
165165 \\[1E-2]
166166 );
167167}
168168
169test "y_number_real_capital_e_pos_exp" {
169test "json.test.y_number_real_capital_e_pos_exp" {
170170 ok(
171171 \\[1E+2]
172172 );
173173}
174174
175test "y_number_real_exponent" {
175test "json.test.y_number_real_exponent" {
176176 ok(
177177 \\[123e45]
178178 );
179179}
180180
181test "y_number_real_fraction_exponent" {
181test "json.test.y_number_real_fraction_exponent" {
182182 ok(
183183 \\[123.456e78]
184184 );
185185}
186186
187test "y_number_real_neg_exp" {
187test "json.test.y_number_real_neg_exp" {
188188 ok(
189189 \\[1e-2]
190190 );
191191}
192192
193test "y_number_real_pos_exponent" {
193test "json.test.y_number_real_pos_exponent" {
194194 ok(
195195 \\[1e+2]
196196 );
197197}
198198
199test "y_number_simple_int" {
199test "json.test.y_number_simple_int" {
200200 ok(
201201 \\[123]
202202 );
203203}
204204
205test "y_number_simple_real" {
205test "json.test.y_number_simple_real" {
206206 ok(
207207 \\[123.456789]
208208 );
209209}
210210
211test "y_object_basic" {
211test "json.test.y_object_basic" {
212212 ok(
213213 \\{"asd":"sdf"}
214214 );
215215}
216216
217test "y_object_duplicated_key_and_value" {
217test "json.test.y_object_duplicated_key_and_value" {
218218 ok(
219219 \\{"a":"b","a":"b"}
220220 );
221221}
222222
223test "y_object_duplicated_key" {
223test "json.test.y_object_duplicated_key" {
224224 ok(
225225 \\{"a":"b","a":"c"}
226226 );
227227}
228228
229test "y_object_empty" {
229test "json.test.y_object_empty" {
230230 ok(
231231 \\{}
232232 );
233233}
234234
235test "y_object_empty_key" {
235test "json.test.y_object_empty_key" {
236236 ok(
237237 \\{"":0}
238238 );
239239}
240240
241test "y_object_escaped_null_in_key" {
241test "json.test.y_object_escaped_null_in_key" {
242242 ok(
243243 \\{"foo\u0000bar": 42}
244244 );
245245}
246246
247test "y_object_extreme_numbers" {
247test "json.test.y_object_extreme_numbers" {
248248 ok(
249249 \\{ "min": -1.0e+28, "max": 1.0e+28 }
250250 );
251251}
252252
253test "y_object" {
253test "json.test.y_object" {
254254 ok(
255255 \\{"asd":"sdf", "dfg":"fgh"}
256256 );
257257}
258258
259test "y_object_long_strings" {
259test "json.test.y_object_long_strings" {
260260 ok(
261261 \\{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
262262 );
263263}
264264
265test "y_object_simple" {
265test "json.test.y_object_simple" {
266266 ok(
267267 \\{"a":[]}
268268 );
269269}
270270
271test "y_object_string_unicode" {
271test "json.test.y_object_string_unicode" {
272272 ok(
273273 \\{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
274274 );
275275}
276276
277test "y_object_with_newlines" {
277test "json.test.y_object_with_newlines" {
278278 ok(
279279 \\{
280280 \\"a": "b"
......@@ -282,419 +282,419 @@ test "y_object_with_newlines" {
282282 );
283283}
284284
285test "y_string_1_2_3_bytes_UTF-8_sequences" {
285test "json.test.y_string_1_2_3_bytes_UTF-8_sequences" {
286286 ok(
287287 \\["\u0060\u012a\u12AB"]
288288 );
289289}
290290
291test "y_string_accepted_surrogate_pair" {
291test "json.test.y_string_accepted_surrogate_pair" {
292292 ok(
293293 \\["\uD801\udc37"]
294294 );
295295}
296296
297test "y_string_accepted_surrogate_pairs" {
297test "json.test.y_string_accepted_surrogate_pairs" {
298298 ok(
299299 \\["\ud83d\ude39\ud83d\udc8d"]
300300 );
301301}
302302
303test "y_string_allowed_escapes" {
303test "json.test.y_string_allowed_escapes" {
304304 ok(
305305 \\["\"\\\/\b\f\n\r\t"]
306306 );
307307}
308308
309test "y_string_backslash_and_u_escaped_zero" {
309test "json.test.y_string_backslash_and_u_escaped_zero" {
310310 ok(
311311 \\["\\u0000"]
312312 );
313313}
314314
315test "y_string_backslash_doublequotes" {
315test "json.test.y_string_backslash_doublequotes" {
316316 ok(
317317 \\["\""]
318318 );
319319}
320320
321test "y_string_comments" {
321test "json.test.y_string_comments" {
322322 ok(
323323 \\["a/*b*/c/*d//e"]
324324 );
325325}
326326
327test "y_string_double_escape_a" {
327test "json.test.y_string_double_escape_a" {
328328 ok(
329329 \\["\\a"]
330330 );
331331}
332332
333test "y_string_double_escape_n" {
333test "json.test.y_string_double_escape_n" {
334334 ok(
335335 \\["\\n"]
336336 );
337337}
338338
339test "y_string_escaped_control_character" {
339test "json.test.y_string_escaped_control_character" {
340340 ok(
341341 \\["\u0012"]
342342 );
343343}
344344
345test "y_string_escaped_noncharacter" {
345test "json.test.y_string_escaped_noncharacter" {
346346 ok(
347347 \\["\uFFFF"]
348348 );
349349}
350350
351test "y_string_in_array" {
351test "json.test.y_string_in_array" {
352352 ok(
353353 \\["asd"]
354354 );
355355}
356356
357test "y_string_in_array_with_leading_space" {
357test "json.test.y_string_in_array_with_leading_space" {
358358 ok(
359359 \\[ "asd"]
360360 );
361361}
362362
363test "y_string_last_surrogates_1_and_2" {
363test "json.test.y_string_last_surrogates_1_and_2" {
364364 ok(
365365 \\["\uDBFF\uDFFF"]
366366 );
367367}
368368
369test "y_string_nbsp_uescaped" {
369test "json.test.y_string_nbsp_uescaped" {
370370 ok(
371371 \\["new\u00A0line"]
372372 );
373373}
374374
375test "y_string_nonCharacterInUTF-8_U+10FFFF" {
375test "json.test.y_string_nonCharacterInUTF-8_U+10FFFF" {
376376 ok(
377377 \\["􏿿"]
378378 );
379379}
380380
381test "y_string_nonCharacterInUTF-8_U+FFFF" {
381test "json.test.y_string_nonCharacterInUTF-8_U+FFFF" {
382382 ok(
383383 \\["￿"]
384384 );
385385}
386386
387test "y_string_null_escape" {
387test "json.test.y_string_null_escape" {
388388 ok(
389389 \\["\u0000"]
390390 );
391391}
392392
393test "y_string_one-byte-utf-8" {
393test "json.test.y_string_one-byte-utf-8" {
394394 ok(
395395 \\["\u002c"]
396396 );
397397}
398398
399test "y_string_pi" {
399test "json.test.y_string_pi" {
400400 ok(
401401 \\["π"]
402402 );
403403}
404404
405test "y_string_reservedCharacterInUTF-8_U+1BFFF" {
405test "json.test.y_string_reservedCharacterInUTF-8_U+1BFFF" {
406406 ok(
407407 \\["𛿿"]
408408 );
409409}
410410
411test "y_string_simple_ascii" {
411test "json.test.y_string_simple_ascii" {
412412 ok(
413413 \\["asd "]
414414 );
415415}
416416
417test "y_string_space" {
417test "json.test.y_string_space" {
418418 ok(
419419 \\" "
420420 );
421421}
422422
423test "y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF" {
423test "json.test.y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF" {
424424 ok(
425425 \\["\uD834\uDd1e"]
426426 );
427427}
428428
429test "y_string_three-byte-utf-8" {
429test "json.test.y_string_three-byte-utf-8" {
430430 ok(
431431 \\["\u0821"]
432432 );
433433}
434434
435test "y_string_two-byte-utf-8" {
435test "json.test.y_string_two-byte-utf-8" {
436436 ok(
437437 \\["\u0123"]
438438 );
439439}
440440
441test "y_string_u+2028_line_sep" {
441test "json.test.y_string_u+2028_line_sep" {
442442 ok("[\"\xe2\x80\xa8\"]");
443443}
444444
445test "y_string_u+2029_par_sep" {
445test "json.test.y_string_u+2029_par_sep" {
446446 ok("[\"\xe2\x80\xa9\"]");
447447}
448448
449test "y_string_uescaped_newline" {
449test "json.test.y_string_uescaped_newline" {
450450 ok(
451451 \\["new\u000Aline"]
452452 );
453453}
454454
455test "y_string_uEscape" {
455test "json.test.y_string_uEscape" {
456456 ok(
457457 \\["\u0061\u30af\u30EA\u30b9"]
458458 );
459459}
460460
461test "y_string_unescaped_char_delete" {
461test "json.test.y_string_unescaped_char_delete" {
462462 ok("[\"\x7f\"]");
463463}
464464
465test "y_string_unicode_2" {
465test "json.test.y_string_unicode_2" {
466466 ok(
467467 \\["⍂㈴⍂"]
468468 );
469469}
470470
471test "y_string_unicodeEscapedBackslash" {
471test "json.test.y_string_unicodeEscapedBackslash" {
472472 ok(
473473 \\["\u005C"]
474474 );
475475}
476476
477test "y_string_unicode_escaped_double_quote" {
477test "json.test.y_string_unicode_escaped_double_quote" {
478478 ok(
479479 \\["\u0022"]
480480 );
481481}
482482
483test "y_string_unicode" {
483test "json.test.y_string_unicode" {
484484 ok(
485485 \\["\uA66D"]
486486 );
487487}
488488
489test "y_string_unicode_U+10FFFE_nonchar" {
489test "json.test.y_string_unicode_U+10FFFE_nonchar" {
490490 ok(
491491 \\["\uDBFF\uDFFE"]
492492 );
493493}
494494
495test "y_string_unicode_U+1FFFE_nonchar" {
495test "json.test.y_string_unicode_U+1FFFE_nonchar" {
496496 ok(
497497 \\["\uD83F\uDFFE"]
498498 );
499499}
500500
501test "y_string_unicode_U+200B_ZERO_WIDTH_SPACE" {
501test "json.test.y_string_unicode_U+200B_ZERO_WIDTH_SPACE" {
502502 ok(
503503 \\["\u200B"]
504504 );
505505}
506506
507test "y_string_unicode_U+2064_invisible_plus" {
507test "json.test.y_string_unicode_U+2064_invisible_plus" {
508508 ok(
509509 \\["\u2064"]
510510 );
511511}
512512
513test "y_string_unicode_U+FDD0_nonchar" {
513test "json.test.y_string_unicode_U+FDD0_nonchar" {
514514 ok(
515515 \\["\uFDD0"]
516516 );
517517}
518518
519test "y_string_unicode_U+FFFE_nonchar" {
519test "json.test.y_string_unicode_U+FFFE_nonchar" {
520520 ok(
521521 \\["\uFFFE"]
522522 );
523523}
524524
525test "y_string_utf8" {
525test "json.test.y_string_utf8" {
526526 ok(
527527 \\["€𝄞"]
528528 );
529529}
530530
531test "y_string_with_del_character" {
531test "json.test.y_string_with_del_character" {
532532 ok("[\"a\x7fa\"]");
533533}
534534
535test "y_structure_lonely_false" {
535test "json.test.y_structure_lonely_false" {
536536 ok(
537537 \\false
538538 );
539539}
540540
541test "y_structure_lonely_int" {
541test "json.test.y_structure_lonely_int" {
542542 ok(
543543 \\42
544544 );
545545}
546546
547test "y_structure_lonely_negative_real" {
547test "json.test.y_structure_lonely_negative_real" {
548548 ok(
549549 \\-0.1
550550 );
551551}
552552
553test "y_structure_lonely_null" {
553test "json.test.y_structure_lonely_null" {
554554 ok(
555555 \\null
556556 );
557557}
558558
559test "y_structure_lonely_string" {
559test "json.test.y_structure_lonely_string" {
560560 ok(
561561 \\"asd"
562562 );
563563}
564564
565test "y_structure_lonely_true" {
565test "json.test.y_structure_lonely_true" {
566566 ok(
567567 \\true
568568 );
569569}
570570
571test "y_structure_string_empty" {
571test "json.test.y_structure_string_empty" {
572572 ok(
573573 \\""
574574 );
575575}
576576
577test "y_structure_trailing_newline" {
577test "json.test.y_structure_trailing_newline" {
578578 ok(
579579 \\["a"]
580580 );
581581}
582582
583test "y_structure_true_in_array" {
583test "json.test.y_structure_true_in_array" {
584584 ok(
585585 \\[true]
586586 );
587587}
588588
589test "y_structure_whitespace_array" {
589test "json.test.y_structure_whitespace_array" {
590590 ok(" [] ");
591591}
592592
593593////////////////////////////////////////////////////////////////////////////////////////////////////
594594
595test "n_array_1_true_without_comma" {
595test "json.test.n_array_1_true_without_comma" {
596596 err(
597597 \\[1 true]
598598 );
599599}
600600
601test "n_array_a_invalid_utf8" {
601test "json.test.n_array_a_invalid_utf8" {
602602 err(
603603 \\[aå]
604604 );
605605}
606606
607test "n_array_colon_instead_of_comma" {
607test "json.test.n_array_colon_instead_of_comma" {
608608 err(
609609 \\["": 1]
610610 );
611611}
612612
613test "n_array_comma_after_close" {
613test "json.test.n_array_comma_after_close" {
614614 //err(
615615 // \\[""],
616616 //);
617617}
618618
619test "n_array_comma_and_number" {
619test "json.test.n_array_comma_and_number" {
620620 err(
621621 \\[,1]
622622 );
623623}
624624
625test "n_array_double_comma" {
625test "json.test.n_array_double_comma" {
626626 err(
627627 \\[1,,2]
628628 );
629629}
630630
631test "n_array_double_extra_comma" {
631test "json.test.n_array_double_extra_comma" {
632632 err(
633633 \\["x",,]
634634 );
635635}
636636
637test "n_array_extra_close" {
637test "json.test.n_array_extra_close" {
638638 err(
639639 \\["x"]]
640640 );
641641}
642642
643test "n_array_extra_comma" {
643test "json.test.n_array_extra_comma" {
644644 //err(
645645 // \\["",]
646646 //);
647647}
648648
649test "n_array_incomplete_invalid_value" {
649test "json.test.n_array_incomplete_invalid_value" {
650650 err(
651651 \\[x
652652 );
653653}
654654
655test "n_array_incomplete" {
655test "json.test.n_array_incomplete" {
656656 err(
657657 \\["x"
658658 );
659659}
660660
661test "n_array_inner_array_no_comma" {
661test "json.test.n_array_inner_array_no_comma" {
662662 err(
663663 \\[3[4]]
664664 );
665665}
666666
667test "n_array_invalid_utf8" {
667test "json.test.n_array_invalid_utf8" {
668668 err(
669669 \\[ÿ]
670670 );
671671}
672672
673test "n_array_items_separated_by_semicolon" {
673test "json.test.n_array_items_separated_by_semicolon" {
674674 err(
675675 \\[1:2]
676676 );
677677}
678678
679test "n_array_just_comma" {
679test "json.test.n_array_just_comma" {
680680 err(
681681 \\[,]
682682 );
683683}
684684
685test "n_array_just_minus" {
685test "json.test.n_array_just_minus" {
686686 err(
687687 \\[-]
688688 );
689689}
690690
691test "n_array_missing_value" {
691test "json.test.n_array_missing_value" {
692692 err(
693693 \\[ , ""]
694694 );
695695}
696696
697test "n_array_newlines_unclosed" {
697test "json.test.n_array_newlines_unclosed" {
698698 err(
699699 \\["a",
700700 \\4
......@@ -702,41 +702,41 @@ test "n_array_newlines_unclosed" {
702702 );
703703}
704704
705test "n_array_number_and_comma" {
705test "json.test.n_array_number_and_comma" {
706706 err(
707707 \\[1,]
708708 );
709709}
710710
711test "n_array_number_and_several_commas" {
711test "json.test.n_array_number_and_several_commas" {
712712 err(
713713 \\[1,,]
714714 );
715715}
716716
717test "n_array_spaces_vertical_tab_formfeed" {
717test "json.test.n_array_spaces_vertical_tab_formfeed" {
718718 err("[\"\x0aa\"\\f]");
719719}
720720
721test "n_array_star_inside" {
721test "json.test.n_array_star_inside" {
722722 err(
723723 \\[*]
724724 );
725725}
726726
727test "n_array_unclosed" {
727test "json.test.n_array_unclosed" {
728728 err(
729729 \\[""
730730 );
731731}
732732
733test "n_array_unclosed_trailing_comma" {
733test "json.test.n_array_unclosed_trailing_comma" {
734734 err(
735735 \\[1,
736736 );
737737}
738738
739test "n_array_unclosed_with_new_lines" {
739test "json.test.n_array_unclosed_with_new_lines" {
740740 err(
741741 \\[1,
742742 \\1
......@@ -744,956 +744,956 @@ test "n_array_unclosed_with_new_lines" {
744744 );
745745}
746746
747test "n_array_unclosed_with_object_inside" {
747test "json.test.n_array_unclosed_with_object_inside" {
748748 err(
749749 \\[{}
750750 );
751751}
752752
753test "n_incomplete_false" {
753test "json.test.n_incomplete_false" {
754754 err(
755755 \\[fals]
756756 );
757757}
758758
759test "n_incomplete_null" {
759test "json.test.n_incomplete_null" {
760760 err(
761761 \\[nul]
762762 );
763763}
764764
765test "n_incomplete_true" {
765test "json.test.n_incomplete_true" {
766766 err(
767767 \\[tru]
768768 );
769769}
770770
771test "n_multidigit_number_then_00" {
771test "json.test.n_multidigit_number_then_00" {
772772 err("123\x00");
773773}
774774
775test "n_number_0.1.2" {
775test "json.test.n_number_0.1.2" {
776776 err(
777777 \\[0.1.2]
778778 );
779779}
780780
781test "n_number_-01" {
781test "json.test.n_number_-01" {
782782 err(
783783 \\[-01]
784784 );
785785}
786786
787test "n_number_0.3e" {
787test "json.test.n_number_0.3e" {
788788 err(
789789 \\[0.3e]
790790 );
791791}
792792
793test "n_number_0.3e+" {
793test "json.test.n_number_0.3e+" {
794794 err(
795795 \\[0.3e+]
796796 );
797797}
798798
799test "n_number_0_capital_E" {
799test "json.test.n_number_0_capital_E" {
800800 err(
801801 \\[0E]
802802 );
803803}
804804
805test "n_number_0_capital_E+" {
805test "json.test.n_number_0_capital_E+" {
806806 err(
807807 \\[0E+]
808808 );
809809}
810810
811test "n_number_0.e1" {
811test "json.test.n_number_0.e1" {
812812 err(
813813 \\[0.e1]
814814 );
815815}
816816
817test "n_number_0e" {
817test "json.test.n_number_0e" {
818818 err(
819819 \\[0e]
820820 );
821821}
822822
823test "n_number_0e+" {
823test "json.test.n_number_0e+" {
824824 err(
825825 \\[0e+]
826826 );
827827}
828828
829test "n_number_1_000" {
829test "json.test.n_number_1_000" {
830830 err(
831831 \\[1 000.0]
832832 );
833833}
834834
835test "n_number_1.0e-" {
835test "json.test.n_number_1.0e-" {
836836 err(
837837 \\[1.0e-]
838838 );
839839}
840840
841test "n_number_1.0e" {
841test "json.test.n_number_1.0e" {
842842 err(
843843 \\[1.0e]
844844 );
845845}
846846
847test "n_number_1.0e+" {
847test "json.test.n_number_1.0e+" {
848848 err(
849849 \\[1.0e+]
850850 );
851851}
852852
853test "n_number_-1.0." {
853test "json.test.n_number_-1.0." {
854854 err(
855855 \\[-1.0.]
856856 );
857857}
858858
859test "n_number_1eE2" {
859test "json.test.n_number_1eE2" {
860860 err(
861861 \\[1eE2]
862862 );
863863}
864864
865test "n_number_.-1" {
865test "json.test.n_number_.-1" {
866866 err(
867867 \\[.-1]
868868 );
869869}
870870
871test "n_number_+1" {
871test "json.test.n_number_+1" {
872872 err(
873873 \\[+1]
874874 );
875875}
876876
877test "n_number_.2e-3" {
877test "json.test.n_number_.2e-3" {
878878 err(
879879 \\[.2e-3]
880880 );
881881}
882882
883test "n_number_2.e-3" {
883test "json.test.n_number_2.e-3" {
884884 err(
885885 \\[2.e-3]
886886 );
887887}
888888
889test "n_number_2.e+3" {
889test "json.test.n_number_2.e+3" {
890890 err(
891891 \\[2.e+3]
892892 );
893893}
894894
895test "n_number_2.e3" {
895test "json.test.n_number_2.e3" {
896896 err(
897897 \\[2.e3]
898898 );
899899}
900900
901test "n_number_-2." {
901test "json.test.n_number_-2." {
902902 err(
903903 \\[-2.]
904904 );
905905}
906906
907test "n_number_9.e+" {
907test "json.test.n_number_9.e+" {
908908 err(
909909 \\[9.e+]
910910 );
911911}
912912
913test "n_number_expression" {
913test "json.test.n_number_expression" {
914914 err(
915915 \\[1+2]
916916 );
917917}
918918
919test "n_number_hex_1_digit" {
919test "json.test.n_number_hex_1_digit" {
920920 err(
921921 \\[0x1]
922922 );
923923}
924924
925test "n_number_hex_2_digits" {
925test "json.test.n_number_hex_2_digits" {
926926 err(
927927 \\[0x42]
928928 );
929929}
930930
931test "n_number_infinity" {
931test "json.test.n_number_infinity" {
932932 err(
933933 \\[Infinity]
934934 );
935935}
936936
937test "n_number_+Inf" {
937test "json.test.n_number_+Inf" {
938938 err(
939939 \\[+Inf]
940940 );
941941}
942942
943test "n_number_Inf" {
943test "json.test.n_number_Inf" {
944944 err(
945945 \\[Inf]
946946 );
947947}
948948
949test "n_number_invalid+-" {
949test "json.test.n_number_invalid+-" {
950950 err(
951951 \\[0e+-1]
952952 );
953953}
954954
955test "n_number_invalid-negative-real" {
955test "json.test.n_number_invalid-negative-real" {
956956 err(
957957 \\[-123.123foo]
958958 );
959959}
960960
961test "n_number_invalid-utf-8-in-bigger-int" {
961test "json.test.n_number_invalid-utf-8-in-bigger-int" {
962962 err(
963963 \\[123å]
964964 );
965965}
966966
967test "n_number_invalid-utf-8-in-exponent" {
967test "json.test.n_number_invalid-utf-8-in-exponent" {
968968 err(
969969 \\[1e1å]
970970 );
971971}
972972
973test "n_number_invalid-utf-8-in-int" {
973test "json.test.n_number_invalid-utf-8-in-int" {
974974 err(
975975 \\[0å]
976976 );
977977}
978978
979test "n_number_++" {
979test "json.test.n_number_++" {
980980 err(
981981 \\[++1234]
982982 );
983983}
984984
985test "n_number_minus_infinity" {
985test "json.test.n_number_minus_infinity" {
986986 err(
987987 \\[-Infinity]
988988 );
989989}
990990
991test "n_number_minus_sign_with_trailing_garbage" {
991test "json.test.n_number_minus_sign_with_trailing_garbage" {
992992 err(
993993 \\[-foo]
994994 );
995995}
996996
997test "n_number_minus_space_1" {
997test "json.test.n_number_minus_space_1" {
998998 err(
999999 \\[- 1]
10001000 );
10011001}
10021002
1003test "n_number_-NaN" {
1003test "json.test.n_number_-NaN" {
10041004 err(
10051005 \\[-NaN]
10061006 );
10071007}
10081008
1009test "n_number_NaN" {
1009test "json.test.n_number_NaN" {
10101010 err(
10111011 \\[NaN]
10121012 );
10131013}
10141014
1015test "n_number_neg_int_starting_with_zero" {
1015test "json.test.n_number_neg_int_starting_with_zero" {
10161016 err(
10171017 \\[-012]
10181018 );
10191019}
10201020
1021test "n_number_neg_real_without_int_part" {
1021test "json.test.n_number_neg_real_without_int_part" {
10221022 err(
10231023 \\[-.123]
10241024 );
10251025}
10261026
1027test "n_number_neg_with_garbage_at_end" {
1027test "json.test.n_number_neg_with_garbage_at_end" {
10281028 err(
10291029 \\[-1x]
10301030 );
10311031}
10321032
1033test "n_number_real_garbage_after_e" {
1033test "json.test.n_number_real_garbage_after_e" {
10341034 err(
10351035 \\[1ea]
10361036 );
10371037}
10381038
1039test "n_number_real_with_invalid_utf8_after_e" {
1039test "json.test.n_number_real_with_invalid_utf8_after_e" {
10401040 err(
10411041 \\[1eå]
10421042 );
10431043}
10441044
1045test "n_number_real_without_fractional_part" {
1045test "json.test.n_number_real_without_fractional_part" {
10461046 err(
10471047 \\[1.]
10481048 );
10491049}
10501050
1051test "n_number_starting_with_dot" {
1051test "json.test.n_number_starting_with_dot" {
10521052 err(
10531053 \\[.123]
10541054 );
10551055}
10561056
1057test "n_number_U+FF11_fullwidth_digit_one" {
1057test "json.test.n_number_U+FF11_fullwidth_digit_one" {
10581058 err(
10591059 \\[1]
10601060 );
10611061}
10621062
1063test "n_number_with_alpha_char" {
1063test "json.test.n_number_with_alpha_char" {
10641064 err(
10651065 \\[1.8011670033376514H-308]
10661066 );
10671067}
10681068
1069test "n_number_with_alpha" {
1069test "json.test.n_number_with_alpha" {
10701070 err(
10711071 \\[1.2a-3]
10721072 );
10731073}
10741074
1075test "n_number_with_leading_zero" {
1075test "json.test.n_number_with_leading_zero" {
10761076 err(
10771077 \\[012]
10781078 );
10791079}
10801080
1081test "n_object_bad_value" {
1081test "json.test.n_object_bad_value" {
10821082 err(
10831083 \\["x", truth]
10841084 );
10851085}
10861086
1087test "n_object_bracket_key" {
1087test "json.test.n_object_bracket_key" {
10881088 err(
10891089 \\{[: "x"}
10901090 );
10911091}
10921092
1093test "n_object_comma_instead_of_colon" {
1093test "json.test.n_object_comma_instead_of_colon" {
10941094 err(
10951095 \\{"x", null}
10961096 );
10971097}
10981098
1099test "n_object_double_colon" {
1099test "json.test.n_object_double_colon" {
11001100 err(
11011101 \\{"x"::"b"}
11021102 );
11031103}
11041104
1105test "n_object_emoji" {
1105test "json.test.n_object_emoji" {
11061106 err(
11071107 \\{🇨🇭}
11081108 );
11091109}
11101110
1111test "n_object_garbage_at_end" {
1111test "json.test.n_object_garbage_at_end" {
11121112 err(
11131113 \\{"a":"a" 123}
11141114 );
11151115}
11161116
1117test "n_object_key_with_single_quotes" {
1117test "json.test.n_object_key_with_single_quotes" {
11181118 err(
11191119 \\{key: 'value'}
11201120 );
11211121}
11221122
1123test "n_object_lone_continuation_byte_in_key_and_trailing_comma" {
1123test "json.test.n_object_lone_continuation_byte_in_key_and_trailing_comma" {
11241124 err(
11251125 \\{"¹":"0",}
11261126 );
11271127}
11281128
1129test "n_object_missing_colon" {
1129test "json.test.n_object_missing_colon" {
11301130 err(
11311131 \\{"a" b}
11321132 );
11331133}
11341134
1135test "n_object_missing_key" {
1135test "json.test.n_object_missing_key" {
11361136 err(
11371137 \\{:"b"}
11381138 );
11391139}
11401140
1141test "n_object_missing_semicolon" {
1141test "json.test.n_object_missing_semicolon" {
11421142 err(
11431143 \\{"a" "b"}
11441144 );
11451145}
11461146
1147test "n_object_missing_value" {
1147test "json.test.n_object_missing_value" {
11481148 err(
11491149 \\{"a":
11501150 );
11511151}
11521152
1153test "n_object_no-colon" {
1153test "json.test.n_object_no-colon" {
11541154 err(
11551155 \\{"a"
11561156 );
11571157}
11581158
1159test "n_object_non_string_key_but_huge_number_instead" {
1159test "json.test.n_object_non_string_key_but_huge_number_instead" {
11601160 err(
11611161 \\{9999E9999:1}
11621162 );
11631163}
11641164
1165test "n_object_non_string_key" {
1165test "json.test.n_object_non_string_key" {
11661166 err(
11671167 \\{1:1}
11681168 );
11691169}
11701170
1171test "n_object_repeated_null_null" {
1171test "json.test.n_object_repeated_null_null" {
11721172 err(
11731173 \\{null:null,null:null}
11741174 );
11751175}
11761176
1177test "n_object_several_trailing_commas" {
1177test "json.test.n_object_several_trailing_commas" {
11781178 err(
11791179 \\{"id":0,,,,,}
11801180 );
11811181}
11821182
1183test "n_object_single_quote" {
1183test "json.test.n_object_single_quote" {
11841184 err(
11851185 \\{'a':0}
11861186 );
11871187}
11881188
1189test "n_object_trailing_comma" {
1189test "json.test.n_object_trailing_comma" {
11901190 err(
11911191 \\{"id":0,}
11921192 );
11931193}
11941194
1195test "n_object_trailing_comment" {
1195test "json.test.n_object_trailing_comment" {
11961196 err(
11971197 \\{"a":"b"}/**/
11981198 );
11991199}
12001200
1201test "n_object_trailing_comment_open" {
1201test "json.test.n_object_trailing_comment_open" {
12021202 err(
12031203 \\{"a":"b"}/**//
12041204 );
12051205}
12061206
1207test "n_object_trailing_comment_slash_open_incomplete" {
1207test "json.test.n_object_trailing_comment_slash_open_incomplete" {
12081208 err(
12091209 \\{"a":"b"}/
12101210 );
12111211}
12121212
1213test "n_object_trailing_comment_slash_open" {
1213test "json.test.n_object_trailing_comment_slash_open" {
12141214 err(
12151215 \\{"a":"b"}//
12161216 );
12171217}
12181218
1219test "n_object_two_commas_in_a_row" {
1219test "json.test.n_object_two_commas_in_a_row" {
12201220 err(
12211221 \\{"a":"b",,"c":"d"}
12221222 );
12231223}
12241224
1225test "n_object_unquoted_key" {
1225test "json.test.n_object_unquoted_key" {
12261226 err(
12271227 \\{a: "b"}
12281228 );
12291229}
12301230
1231test "n_object_unterminated-value" {
1231test "json.test.n_object_unterminated-value" {
12321232 err(
12331233 \\{"a":"a
12341234 );
12351235}
12361236
1237test "n_object_with_single_string" {
1237test "json.test.n_object_with_single_string" {
12381238 err(
12391239 \\{ "foo" : "bar", "a" }
12401240 );
12411241}
12421242
1243test "n_object_with_trailing_garbage" {
1243test "json.test.n_object_with_trailing_garbage" {
12441244 err(
12451245 \\{"a":"b"}#
12461246 );
12471247}
12481248
1249test "n_single_space" {
1249test "json.test.n_single_space" {
12501250 err(" ");
12511251}
12521252
1253test "n_string_1_surrogate_then_escape" {
1253test "json.test.n_string_1_surrogate_then_escape" {
12541254 err(
12551255 \\["\uD800\"]
12561256 );
12571257}
12581258
1259test "n_string_1_surrogate_then_escape_u1" {
1259test "json.test.n_string_1_surrogate_then_escape_u1" {
12601260 err(
12611261 \\["\uD800\u1"]
12621262 );
12631263}
12641264
1265test "n_string_1_surrogate_then_escape_u1x" {
1265test "json.test.n_string_1_surrogate_then_escape_u1x" {
12661266 err(
12671267 \\["\uD800\u1x"]
12681268 );
12691269}
12701270
1271test "n_string_1_surrogate_then_escape_u" {
1271test "json.test.n_string_1_surrogate_then_escape_u" {
12721272 err(
12731273 \\["\uD800\u"]
12741274 );
12751275}
12761276
1277test "n_string_accentuated_char_no_quotes" {
1277test "json.test.n_string_accentuated_char_no_quotes" {
12781278 err(
12791279 \\[é]
12801280 );
12811281}
12821282
1283test "n_string_backslash_00" {
1283test "json.test.n_string_backslash_00" {
12841284 err("[\"\x00\"]");
12851285}
12861286
1287test "n_string_escaped_backslash_bad" {
1287test "json.test.n_string_escaped_backslash_bad" {
12881288 err(
12891289 \\["\\\"]
12901290 );
12911291}
12921292
1293test "n_string_escaped_ctrl_char_tab" {
1293test "json.test.n_string_escaped_ctrl_char_tab" {
12941294 err("\x5b\x22\x5c\x09\x22\x5d");
12951295}
12961296
1297test "n_string_escaped_emoji" {
1297test "json.test.n_string_escaped_emoji" {
12981298 err("[\"\x5c\xc3\xb0\xc2\x9f\xc2\x8c\xc2\x80\"]");
12991299}
13001300
1301test "n_string_escape_x" {
1301test "json.test.n_string_escape_x" {
13021302 err(
13031303 \\["\x00"]
13041304 );
13051305}
13061306
1307test "n_string_incomplete_escaped_character" {
1307test "json.test.n_string_incomplete_escaped_character" {
13081308 err(
13091309 \\["\u00A"]
13101310 );
13111311}
13121312
1313test "n_string_incomplete_escape" {
1313test "json.test.n_string_incomplete_escape" {
13141314 err(
13151315 \\["\"]
13161316 );
13171317}
13181318
1319test "n_string_incomplete_surrogate_escape_invalid" {
1319test "json.test.n_string_incomplete_surrogate_escape_invalid" {
13201320 err(
13211321 \\["\uD800\uD800\x"]
13221322 );
13231323}
13241324
1325test "n_string_incomplete_surrogate" {
1325test "json.test.n_string_incomplete_surrogate" {
13261326 err(
13271327 \\["\uD834\uDd"]
13281328 );
13291329}
13301330
1331test "n_string_invalid_backslash_esc" {
1331test "json.test.n_string_invalid_backslash_esc" {
13321332 err(
13331333 \\["\a"]
13341334 );
13351335}
13361336
1337test "n_string_invalid_unicode_escape" {
1337test "json.test.n_string_invalid_unicode_escape" {
13381338 err(
13391339 \\["\uqqqq"]
13401340 );
13411341}
13421342
1343test "n_string_invalid_utf8_after_escape" {
1343test "json.test.n_string_invalid_utf8_after_escape" {
13441344 err("[\"\\\x75\xc3\xa5\"]");
13451345}
13461346
1347test "n_string_invalid-utf-8-in-escape" {
1347test "json.test.n_string_invalid-utf-8-in-escape" {
13481348 err(
13491349 \\["\uå"]
13501350 );
13511351}
13521352
1353test "n_string_leading_uescaped_thinspace" {
1353test "json.test.n_string_leading_uescaped_thinspace" {
13541354 err(
13551355 \\[\u0020"asd"]
13561356 );
13571357}
13581358
1359test "n_string_no_quotes_with_bad_escape" {
1359test "json.test.n_string_no_quotes_with_bad_escape" {
13601360 err(
13611361 \\[\n]
13621362 );
13631363}
13641364
1365test "n_string_single_doublequote" {
1365test "json.test.n_string_single_doublequote" {
13661366 err(
13671367 \\"
13681368 );
13691369}
13701370
1371test "n_string_single_quote" {
1371test "json.test.n_string_single_quote" {
13721372 err(
13731373 \\['single quote']
13741374 );
13751375}
13761376
1377test "n_string_single_string_no_double_quotes" {
1377test "json.test.n_string_single_string_no_double_quotes" {
13781378 err(
13791379 \\abc
13801380 );
13811381}
13821382
1383test "n_string_start_escape_unclosed" {
1383test "json.test.n_string_start_escape_unclosed" {
13841384 err(
13851385 \\["\
13861386 );
13871387}
13881388
1389test "n_string_unescaped_crtl_char" {
1389test "json.test.n_string_unescaped_crtl_char" {
13901390 err("[\"a\x00a\"]");
13911391}
13921392
1393test "n_string_unescaped_newline" {
1393test "json.test.n_string_unescaped_newline" {
13941394 err(
13951395 \\["new
13961396 \\line"]
13971397 );
13981398}
13991399
1400test "n_string_unescaped_tab" {
1400test "json.test.n_string_unescaped_tab" {
14011401 err("[\"\t\"]");
14021402}
14031403
1404test "n_string_unicode_CapitalU" {
1404test "json.test.n_string_unicode_CapitalU" {
14051405 err(
14061406 \\"\UA66D"
14071407 );
14081408}
14091409
1410test "n_string_with_trailing_garbage" {
1410test "json.test.n_string_with_trailing_garbage" {
14111411 err(
14121412 \\""x
14131413 );
14141414}
14151415
1416test "n_structure_100000_opening_arrays" {
1416test "json.test.n_structure_100000_opening_arrays" {
14171417 err("[" ** 100000);
14181418}
14191419
1420test "n_structure_angle_bracket_." {
1420test "json.test.n_structure_angle_bracket_." {
14211421 err(
14221422 \\<.>
14231423 );
14241424}
14251425
1426test "n_structure_angle_bracket_null" {
1426test "json.test.n_structure_angle_bracket_null" {
14271427 err(
14281428 \\[<null>]
14291429 );
14301430}
14311431
1432test "n_structure_array_trailing_garbage" {
1432test "json.test.n_structure_array_trailing_garbage" {
14331433 err(
14341434 \\[1]x
14351435 );
14361436}
14371437
1438test "n_structure_array_with_extra_array_close" {
1438test "json.test.n_structure_array_with_extra_array_close" {
14391439 err(
14401440 \\[1]]
14411441 );
14421442}
14431443
1444test "n_structure_array_with_unclosed_string" {
1444test "json.test.n_structure_array_with_unclosed_string" {
14451445 err(
14461446 \\["asd]
14471447 );
14481448}
14491449
1450test "n_structure_ascii-unicode-identifier" {
1450test "json.test.n_structure_ascii-unicode-identifier" {
14511451 err(
14521452 \\aå
14531453 );
14541454}
14551455
1456test "n_structure_capitalized_True" {
1456test "json.test.n_structure_capitalized_True" {
14571457 err(
14581458 \\[True]
14591459 );
14601460}
14611461
1462test "n_structure_close_unopened_array" {
1462test "json.test.n_structure_close_unopened_array" {
14631463 err(
14641464 \\1]
14651465 );
14661466}
14671467
1468test "n_structure_comma_instead_of_closing_brace" {
1468test "json.test.n_structure_comma_instead_of_closing_brace" {
14691469 err(
14701470 \\{"x": true,
14711471 );
14721472}
14731473
1474test "n_structure_double_array" {
1474test "json.test.n_structure_double_array" {
14751475 err(
14761476 \\[][]
14771477 );
14781478}
14791479
1480test "n_structure_end_array" {
1480test "json.test.n_structure_end_array" {
14811481 err(
14821482 \\]
14831483 );
14841484}
14851485
1486test "n_structure_incomplete_UTF8_BOM" {
1486test "json.test.n_structure_incomplete_UTF8_BOM" {
14871487 err(
14881488 \\ï»{}
14891489 );
14901490}
14911491
1492test "n_structure_lone-invalid-utf-8" {
1492test "json.test.n_structure_lone-invalid-utf-8" {
14931493 err(
14941494 \\å
14951495 );
14961496}
14971497
1498test "n_structure_lone-open-bracket" {
1498test "json.test.n_structure_lone-open-bracket" {
14991499 err(
15001500 \\[
15011501 );
15021502}
15031503
1504test "n_structure_no_data" {
1504test "json.test.n_structure_no_data" {
15051505 err(
15061506 \\
15071507 );
15081508}
15091509
1510test "n_structure_null-byte-outside-string" {
1510test "json.test.n_structure_null-byte-outside-string" {
15111511 err("[\x00]");
15121512}
15131513
1514test "n_structure_number_with_trailing_garbage" {
1514test "json.test.n_structure_number_with_trailing_garbage" {
15151515 err(
15161516 \\2@
15171517 );
15181518}
15191519
1520test "n_structure_object_followed_by_closing_object" {
1520test "json.test.n_structure_object_followed_by_closing_object" {
15211521 err(
15221522 \\{}}
15231523 );
15241524}
15251525
1526test "n_structure_object_unclosed_no_value" {
1526test "json.test.n_structure_object_unclosed_no_value" {
15271527 err(
15281528 \\{"":
15291529 );
15301530}
15311531
1532test "n_structure_object_with_comment" {
1532test "json.test.n_structure_object_with_comment" {
15331533 err(
15341534 \\{"a":/*comment*/"b"}
15351535 );
15361536}
15371537
1538test "n_structure_object_with_trailing_garbage" {
1538test "json.test.n_structure_object_with_trailing_garbage" {
15391539 err(
15401540 \\{"a": true} "x"
15411541 );
15421542}
15431543
1544test "n_structure_open_array_apostrophe" {
1544test "json.test.n_structure_open_array_apostrophe" {
15451545 err(
15461546 \\['
15471547 );
15481548}
15491549
1550test "n_structure_open_array_comma" {
1550test "json.test.n_structure_open_array_comma" {
15511551 err(
15521552 \\[,
15531553 );
15541554}
15551555
1556test "n_structure_open_array_object" {
1556test "json.test.n_structure_open_array_object" {
15571557 err("[{\"\":" ** 50000);
15581558}
15591559
1560test "n_structure_open_array_open_object" {
1560test "json.test.n_structure_open_array_open_object" {
15611561 err(
15621562 \\[{
15631563 );
15641564}
15651565
1566test "n_structure_open_array_open_string" {
1566test "json.test.n_structure_open_array_open_string" {
15671567 err(
15681568 \\["a
15691569 );
15701570}
15711571
1572test "n_structure_open_array_string" {
1572test "json.test.n_structure_open_array_string" {
15731573 err(
15741574 \\["a"
15751575 );
15761576}
15771577
1578test "n_structure_open_object_close_array" {
1578test "json.test.n_structure_open_object_close_array" {
15791579 err(
15801580 \\{]
15811581 );
15821582}
15831583
1584test "n_structure_open_object_comma" {
1584test "json.test.n_structure_open_object_comma" {
15851585 err(
15861586 \\{,
15871587 );
15881588}
15891589
1590test "n_structure_open_object" {
1590test "json.test.n_structure_open_object" {
15911591 err(
15921592 \\{
15931593 );
15941594}
15951595
1596test "n_structure_open_object_open_array" {
1596test "json.test.n_structure_open_object_open_array" {
15971597 err(
15981598 \\{[
15991599 );
16001600}
16011601
1602test "n_structure_open_object_open_string" {
1602test "json.test.n_structure_open_object_open_string" {
16031603 err(
16041604 \\{"a
16051605 );
16061606}
16071607
1608test "n_structure_open_object_string_with_apostrophes" {
1608test "json.test.n_structure_open_object_string_with_apostrophes" {
16091609 err(
16101610 \\{'a'
16111611 );
16121612}
16131613
1614test "n_structure_open_open" {
1614test "json.test.n_structure_open_open" {
16151615 err(
16161616 \\["\{["\{["\{["\{
16171617 );
16181618}
16191619
1620test "n_structure_single_eacute" {
1620test "json.test.n_structure_single_eacute" {
16211621 err(
16221622 \\é
16231623 );
16241624}
16251625
1626test "n_structure_single_star" {
1626test "json.test.n_structure_single_star" {
16271627 err(
16281628 \\*
16291629 );
16301630}
16311631
1632test "n_structure_trailing_#" {
1632test "json.test.n_structure_trailing_#" {
16331633 err(
16341634 \\{"a":"b"}#{}
16351635 );
16361636}
16371637
1638test "n_structure_U+2060_word_joined" {
1638test "json.test.n_structure_U+2060_word_joined" {
16391639 err(
16401640 \\[⁠]
16411641 );
16421642}
16431643
1644test "n_structure_uescaped_LF_before_string" {
1644test "json.test.n_structure_uescaped_LF_before_string" {
16451645 err(
16461646 \\[\u000A""]
16471647 );
16481648}
16491649
1650test "n_structure_unclosed_array" {
1650test "json.test.n_structure_unclosed_array" {
16511651 err(
16521652 \\[1
16531653 );
16541654}
16551655
1656test "n_structure_unclosed_array_partial_null" {
1656test "json.test.n_structure_unclosed_array_partial_null" {
16571657 err(
16581658 \\[ false, nul
16591659 );
16601660}
16611661
1662test "n_structure_unclosed_array_unfinished_false" {
1662test "json.test.n_structure_unclosed_array_unfinished_false" {
16631663 err(
16641664 \\[ true, fals
16651665 );
16661666}
16671667
1668test "n_structure_unclosed_array_unfinished_true" {
1668test "json.test.n_structure_unclosed_array_unfinished_true" {
16691669 err(
16701670 \\[ false, tru
16711671 );
16721672}
16731673
1674test "n_structure_unclosed_object" {
1674test "json.test.n_structure_unclosed_object" {
16751675 err(
16761676 \\{"asd":"asd"
16771677 );
16781678}
16791679
1680test "n_structure_unicode-identifier" {
1680test "json.test.n_structure_unicode-identifier" {
16811681 err(
16821682 \\Ã¥
16831683 );
16841684}
16851685
1686test "n_structure_UTF8_BOM_no_data" {
1686test "json.test.n_structure_UTF8_BOM_no_data" {
16871687 err(
16881688 \\
16891689 );
16901690}
16911691
1692test "n_structure_whitespace_formfeed" {
1692test "json.test.n_structure_whitespace_formfeed" {
16931693 err("[\x0c]");
16941694}
16951695
1696test "n_structure_whitespace_U+2060_word_joiner" {
1696test "json.test.n_structure_whitespace_U+2060_word_joiner" {
16971697 err(
16981698 \\[⁠]
16991699 );
......@@ -1701,203 +1701,203 @@ test "n_structure_whitespace_U+2060_word_joiner" {
17011701
17021702////////////////////////////////////////////////////////////////////////////////////////////////////
17031703
1704test "i_number_double_huge_neg_exp" {
1704test "json.test.i_number_double_huge_neg_exp" {
17051705 any(
17061706 \\[123.456e-789]
17071707 );
17081708}
17091709
1710test "i_number_huge_exp" {
1710test "json.test.i_number_huge_exp" {
17111711 any(
17121712 \\[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
17131713 );
17141714}
17151715
1716test "i_number_neg_int_huge_exp" {
1716test "json.test.i_number_neg_int_huge_exp" {
17171717 any(
17181718 \\[-1e+9999]
17191719 );
17201720}
17211721
1722test "i_number_pos_double_huge_exp" {
1722test "json.test.i_number_pos_double_huge_exp" {
17231723 any(
17241724 \\[1.5e+9999]
17251725 );
17261726}
17271727
1728test "i_number_real_neg_overflow" {
1728test "json.test.i_number_real_neg_overflow" {
17291729 any(
17301730 \\[-123123e100000]
17311731 );
17321732}
17331733
1734test "i_number_real_pos_overflow" {
1734test "json.test.i_number_real_pos_overflow" {
17351735 any(
17361736 \\[123123e100000]
17371737 );
17381738}
17391739
1740test "i_number_real_underflow" {
1740test "json.test.i_number_real_underflow" {
17411741 any(
17421742 \\[123e-10000000]
17431743 );
17441744}
17451745
1746test "i_number_too_big_neg_int" {
1746test "json.test.i_number_too_big_neg_int" {
17471747 any(
17481748 \\[-123123123123123123123123123123]
17491749 );
17501750}
17511751
1752test "i_number_too_big_pos_int" {
1752test "json.test.i_number_too_big_pos_int" {
17531753 any(
17541754 \\[100000000000000000000]
17551755 );
17561756}
17571757
1758test "i_number_very_big_negative_int" {
1758test "json.test.i_number_very_big_negative_int" {
17591759 any(
17601760 \\[-237462374673276894279832749832423479823246327846]
17611761 );
17621762}
17631763
1764test "i_object_key_lone_2nd_surrogate" {
1764test "json.test.i_object_key_lone_2nd_surrogate" {
17651765 any(
17661766 \\{"\uDFAA":0}
17671767 );
17681768}
17691769
1770test "i_string_1st_surrogate_but_2nd_missing" {
1770test "json.test.i_string_1st_surrogate_but_2nd_missing" {
17711771 any(
17721772 \\["\uDADA"]
17731773 );
17741774}
17751775
1776test "i_string_1st_valid_surrogate_2nd_invalid" {
1776test "json.test.i_string_1st_valid_surrogate_2nd_invalid" {
17771777 any(
17781778 \\["\uD888\u1234"]
17791779 );
17801780}
17811781
1782test "i_string_incomplete_surrogate_and_escape_valid" {
1782test "json.test.i_string_incomplete_surrogate_and_escape_valid" {
17831783 any(
17841784 \\["\uD800\n"]
17851785 );
17861786}
17871787
1788test "i_string_incomplete_surrogate_pair" {
1788test "json.test.i_string_incomplete_surrogate_pair" {
17891789 any(
17901790 \\["\uDd1ea"]
17911791 );
17921792}
17931793
1794test "i_string_incomplete_surrogates_escape_valid" {
1794test "json.test.i_string_incomplete_surrogates_escape_valid" {
17951795 any(
17961796 \\["\uD800\uD800\n"]
17971797 );
17981798}
17991799
1800test "i_string_invalid_lonely_surrogate" {
1800test "json.test.i_string_invalid_lonely_surrogate" {
18011801 any(
18021802 \\["\ud800"]
18031803 );
18041804}
18051805
1806test "i_string_invalid_surrogate" {
1806test "json.test.i_string_invalid_surrogate" {
18071807 any(
18081808 \\["\ud800abc"]
18091809 );
18101810}
18111811
1812test "i_string_invalid_utf-8" {
1812test "json.test.i_string_invalid_utf-8" {
18131813 any(
18141814 \\["ÿ"]
18151815 );
18161816}
18171817
1818test "i_string_inverted_surrogates_U+1D11E" {
1818test "json.test.i_string_inverted_surrogates_U+1D11E" {
18191819 any(
18201820 \\["\uDd1e\uD834"]
18211821 );
18221822}
18231823
1824test "i_string_iso_latin_1" {
1824test "json.test.i_string_iso_latin_1" {
18251825 any(
18261826 \\["é"]
18271827 );
18281828}
18291829
1830test "i_string_lone_second_surrogate" {
1830test "json.test.i_string_lone_second_surrogate" {
18311831 any(
18321832 \\["\uDFAA"]
18331833 );
18341834}
18351835
1836test "i_string_lone_utf8_continuation_byte" {
1836test "json.test.i_string_lone_utf8_continuation_byte" {
18371837 any(
18381838 \\[""]
18391839 );
18401840}
18411841
1842test "i_string_not_in_unicode_range" {
1842test "json.test.i_string_not_in_unicode_range" {
18431843 any(
18441844 \\["ô¿¿¿"]
18451845 );
18461846}
18471847
1848test "i_string_overlong_sequence_2_bytes" {
1848test "json.test.i_string_overlong_sequence_2_bytes" {
18491849 any(
18501850 \\["À¯"]
18511851 );
18521852}
18531853
1854test "i_string_overlong_sequence_6_bytes" {
1854test "json.test.i_string_overlong_sequence_6_bytes" {
18551855 any(
18561856 \\["üƒ¿¿¿¿"]
18571857 );
18581858}
18591859
1860test "i_string_overlong_sequence_6_bytes_null" {
1860test "json.test.i_string_overlong_sequence_6_bytes_null" {
18611861 any(
18621862 \\["ü€€€€€"]
18631863 );
18641864}
18651865
1866test "i_string_truncated-utf-8" {
1866test "json.test.i_string_truncated-utf-8" {
18671867 any(
18681868 \\["àÿ"]
18691869 );
18701870}
18711871
1872test "i_string_utf16BE_no_BOM" {
1872test "json.test.i_string_utf16BE_no_BOM" {
18731873 any("\x00\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d");
18741874}
18751875
1876test "i_string_utf16LE_no_BOM" {
1876test "json.test.i_string_utf16LE_no_BOM" {
18771877 any("\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
18781878}
18791879
1880test "i_string_UTF-16LE_with_BOM" {
1880test "json.test.i_string_UTF-16LE_with_BOM" {
18811881 any("\xc3\xbf\xc3\xbe\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
18821882}
18831883
1884test "i_string_UTF-8_invalid_sequence" {
1884test "json.test.i_string_UTF-8_invalid_sequence" {
18851885 any(
18861886 \\["日шú"]
18871887 );
18881888}
18891889
1890test "i_string_UTF8_surrogate_U+D800" {
1890test "json.test.i_string_UTF8_surrogate_U+D800" {
18911891 any(
18921892 \\["í €"]
18931893 );
18941894}
18951895
1896test "i_structure_500_nested_arrays" {
1896test "json.test.i_structure_500_nested_arrays" {
18971897 any(("[" ** 500) ++ ("]" ** 500));
18981898}
18991899
1900test "i_structure_UTF-8_BOM_empty_object" {
1900test "json.test.i_structure_UTF-8_BOM_empty_object" {
19011901 any(
19021902 \\{}
19031903 );
std/linked_list.zig+96
......@@ -82,6 +82,28 @@ pub fn LinkedList(comptime T: type) type {
8282 list.len += 1;
8383 }
8484
85 /// Concatenate list2 onto the end of list1, removing all entries from the former.
86 ///
87 /// Arguments:
88 /// list1: the list to concatenate onto
89 /// list2: the list to be concatenated
90 pub fn concatByMoving(list1: *Self, list2: *Self) void {
91 const l2_first = list2.first orelse return;
92 if (list1.last) |l1_last| {
93 l1_last.next = list2.first;
94 l2_first.prev = list1.last;
95 list1.len += list2.len;
96 } else {
97 // list1 was empty
98 list1.first = list2.first;
99 list1.len = list2.len;
100 }
101 list1.last = list2.last;
102 list2.first = null;
103 list2.last = null;
104 list2.len = 0;
105 }
106
85107 /// Insert a new node at the end of the list.
86108 ///
87109 /// Arguments:
......@@ -247,3 +269,77 @@ test "basic linked list test" {
247269 assert(list.last.?.data == 4);
248270 assert(list.len == 2);
249271}
272
273test "linked list concatenation" {
274 const allocator = debug.global_allocator;
275 var list1 = LinkedList(u32).init();
276 var list2 = LinkedList(u32).init();
277
278 var one = try list1.createNode(1, allocator);
279 defer list1.destroyNode(one, allocator);
280 var two = try list1.createNode(2, allocator);
281 defer list1.destroyNode(two, allocator);
282 var three = try list1.createNode(3, allocator);
283 defer list1.destroyNode(three, allocator);
284 var four = try list1.createNode(4, allocator);
285 defer list1.destroyNode(four, allocator);
286 var five = try list1.createNode(5, allocator);
287 defer list1.destroyNode(five, allocator);
288
289 list1.append(one);
290 list1.append(two);
291 list2.append(three);
292 list2.append(four);
293 list2.append(five);
294
295 list1.concatByMoving(&list2);
296
297 assert(list1.last == five);
298 assert(list1.len == 5);
299 assert(list2.first == null);
300 assert(list2.last == null);
301 assert(list2.len == 0);
302
303 // Traverse forwards.
304 {
305 var it = list1.first;
306 var index: u32 = 1;
307 while (it) |node| : (it = node.next) {
308 assert(node.data == index);
309 index += 1;
310 }
311 }
312
313 // Traverse backwards.
314 {
315 var it = list1.last;
316 var index: u32 = 1;
317 while (it) |node| : (it = node.prev) {
318 assert(node.data == (6 - index));
319 index += 1;
320 }
321 }
322
323 // Swap them back, this verifies that concating to an empty list works.
324 list2.concatByMoving(&list1);
325
326 // Traverse forwards.
327 {
328 var it = list2.first;
329 var index: u32 = 1;
330 while (it) |node| : (it = node.next) {
331 assert(node.data == index);
332 index += 1;
333 }
334 }
335
336 // Traverse backwards.
337 {
338 var it = list2.last;
339 var index: u32 = 1;
340 while (it) |node| : (it = node.prev) {
341 assert(node.data == (6 - index));
342 index += 1;
343 }
344 }
345}
std/math/index.zig+70
......@@ -6,6 +6,13 @@ const assert = std.debug.assert;
66pub const e = 2.71828182845904523536028747135266249775724709369995;
77pub const pi = 3.14159265358979323846264338327950288419716939937510;
88
9// From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128)
10pub const f128_true_min = @bitCast(f128, u128(0x00000000000000000000000000000001));
11pub const f128_min = @bitCast(f128, u128(0x00010000000000000000000000000000));
12pub const f128_max = @bitCast(f128, u128(0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
13pub const f128_epsilon = @bitCast(f128, u128(0x3F8F0000000000000000000000000000));
14pub const f128_toint = 1.0 / f128_epsilon;
15
916// float.h details
1017pub const f64_true_min = 4.94065645841246544177e-324;
1118pub const f64_min = 2.2250738585072014e-308;
......@@ -365,6 +372,69 @@ pub fn Log2Int(comptime T: type) type {
365372 return @IntType(false, count);
366373}
367374
375pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
376 assert(from <= to);
377 if (from == 0 and to == 0) {
378 return u0;
379 }
380 const is_signed = from < 0;
381 const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement
382 const base = log2(largest_positive_integer);
383 const upper = (1 << base) - 1;
384 var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
385 if (is_signed) {
386 magnitude_bits += 1;
387 }
388 return @IntType(is_signed, magnitude_bits);
389}
390
391test "math.IntFittingRange" {
392 assert(IntFittingRange(0, 0) == u0);
393 assert(IntFittingRange(0, 1) == u1);
394 assert(IntFittingRange(0, 2) == u2);
395 assert(IntFittingRange(0, 3) == u2);
396 assert(IntFittingRange(0, 4) == u3);
397 assert(IntFittingRange(0, 7) == u3);
398 assert(IntFittingRange(0, 8) == u4);
399 assert(IntFittingRange(0, 9) == u4);
400 assert(IntFittingRange(0, 15) == u4);
401 assert(IntFittingRange(0, 16) == u5);
402 assert(IntFittingRange(0, 17) == u5);
403 assert(IntFittingRange(0, 4095) == u12);
404 assert(IntFittingRange(2000, 4095) == u12);
405 assert(IntFittingRange(0, 4096) == u13);
406 assert(IntFittingRange(2000, 4096) == u13);
407 assert(IntFittingRange(0, 4097) == u13);
408 assert(IntFittingRange(2000, 4097) == u13);
409 assert(IntFittingRange(0, 123456789123456798123456789) == u87);
410 assert(IntFittingRange(0, 123456789123456798123456789123456789123456798123456789) == u177);
411
412 assert(IntFittingRange(-1, -1) == i1);
413 assert(IntFittingRange(-1, 0) == i1);
414 assert(IntFittingRange(-1, 1) == i2);
415 assert(IntFittingRange(-2, -2) == i2);
416 assert(IntFittingRange(-2, -1) == i2);
417 assert(IntFittingRange(-2, 0) == i2);
418 assert(IntFittingRange(-2, 1) == i2);
419 assert(IntFittingRange(-2, 2) == i3);
420 assert(IntFittingRange(-1, 2) == i3);
421 assert(IntFittingRange(-1, 3) == i3);
422 assert(IntFittingRange(-1, 4) == i4);
423 assert(IntFittingRange(-1, 7) == i4);
424 assert(IntFittingRange(-1, 8) == i5);
425 assert(IntFittingRange(-1, 9) == i5);
426 assert(IntFittingRange(-1, 15) == i5);
427 assert(IntFittingRange(-1, 16) == i6);
428 assert(IntFittingRange(-1, 17) == i6);
429 assert(IntFittingRange(-1, 4095) == i13);
430 assert(IntFittingRange(-4096, 4095) == i13);
431 assert(IntFittingRange(-1, 4096) == i14);
432 assert(IntFittingRange(-4097, 4095) == i14);
433 assert(IntFittingRange(-1, 4097) == i14);
434 assert(IntFittingRange(-1, 123456789123456798123456789) == i88);
435 assert(IntFittingRange(-1, 123456789123456798123456789123456789123456798123456789) == i178);
436}
437
368438test "math overflow functions" {
369439 testOverflow();
370440 comptime testOverflow();
std/mem.zig+277-148
......@@ -410,12 +410,8 @@ test "mem.indexOf" {
410410/// Reads an integer from memory with size equal to bytes.len.
411411/// T specifies the return type, which must be large enough to store
412412/// the result.
413/// See also ::readIntBE or ::readIntLE.
414pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T {
415 if (T.bit_count == 8) {
416 return bytes[0];
417 }
418 var result: T = 0;
413pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin.Endian) ReturnType {
414 var result: ReturnType = 0;
419415 switch (endian) {
420416 builtin.Endian.Big => {
421417 for (bytes) |b| {
......@@ -423,172 +419,270 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T {
423419 }
424420 },
425421 builtin.Endian.Little => {
426 const ShiftType = math.Log2Int(T);
422 const ShiftType = math.Log2Int(ReturnType);
427423 for (bytes) |b, index| {
428 result = result | (T(b) << @intCast(ShiftType, index * 8));
424 result = result | (ReturnType(b) << @intCast(ShiftType, index * 8));
429425 }
430426 },
431427 }
432428 return result;
433429}
434430
435/// Reads a big-endian int of type T from bytes.
436/// bytes.len must be exactly @sizeOf(T).
437pub fn readIntBE(comptime T: type, bytes: []const u8) T {
438 if (T.is_signed) {
439 return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes));
440 }
441 assert(bytes.len == @sizeOf(T));
442 if (T == u8) return bytes[0];
443 var result: T = 0;
444 {
445 comptime var i = 0;
446 inline while (i < @sizeOf(T)) : (i += 1) {
447 result = (result << 8) | T(bytes[i]);
448 }
431/// Reads an integer from memory with bit count specified by T.
432/// The bit count of T must be evenly divisible by 8.
433/// This function cannot fail and cannot cause undefined behavior.
434/// Assumes the endianness of memory is native. This means the function can
435/// simply pointer cast memory.
436pub fn readIntNative(comptime T: type, bytes: *const [@sizeOf(T)]u8) T {
437 comptime assert(T.bit_count % 8 == 0);
438 return @ptrCast(*align(1) const T, bytes).*;
439}
440
441/// Reads an integer from memory with bit count specified by T.
442/// The bit count of T must be evenly divisible by 8.
443/// This function cannot fail and cannot cause undefined behavior.
444/// Assumes the endianness of memory is foreign, so it must byte-swap.
445pub fn readIntForeign(comptime T: type, bytes: *const [@sizeOf(T)]u8) T {
446 return @bswap(T, readIntNative(T, bytes));
447}
448
449pub const readIntLittle = switch (builtin.endian) {
450 builtin.Endian.Little => readIntNative,
451 builtin.Endian.Big => readIntForeign,
452};
453
454pub const readIntBig = switch (builtin.endian) {
455 builtin.Endian.Little => readIntForeign,
456 builtin.Endian.Big => readIntNative,
457};
458
459/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
460/// and ignores extra bytes.
461/// Note that @sizeOf(u24) is 3.
462/// The bit count of T must be evenly divisible by 8.
463/// Assumes the endianness of memory is native. This means the function can
464/// simply pointer cast memory.
465pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T {
466 assert(@sizeOf(u24) == 3);
467 assert(bytes.len >= @sizeOf(T));
468 // TODO https://github.com/ziglang/zig/issues/863
469 return readIntNative(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr));
470}
471
472/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
473/// and ignores extra bytes.
474/// Note that @sizeOf(u24) is 3.
475/// The bit count of T must be evenly divisible by 8.
476/// Assumes the endianness of memory is foreign, so it must byte-swap.
477pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T {
478 return @bswap(T, readIntSliceNative(T, bytes));
479}
480
481pub const readIntSliceLittle = switch (builtin.endian) {
482 builtin.Endian.Little => readIntSliceNative,
483 builtin.Endian.Big => readIntSliceForeign,
484};
485
486pub const readIntSliceBig = switch (builtin.endian) {
487 builtin.Endian.Little => readIntSliceForeign,
488 builtin.Endian.Big => readIntSliceNative,
489};
490
491/// Reads an integer from memory with bit count specified by T.
492/// The bit count of T must be evenly divisible by 8.
493/// This function cannot fail and cannot cause undefined behavior.
494pub fn readInt(comptime T: type, bytes: *const [@sizeOf(T)]u8, endian: builtin.Endian) T {
495 if (endian == builtin.endian) {
496 return readIntNative(T, bytes);
497 } else {
498 return readIntForeign(T, bytes);
449499 }
450 return result;
451500}
452501
453/// Reads a little-endian int of type T from bytes.
454/// bytes.len must be exactly @sizeOf(T).
455pub fn readIntLE(comptime T: type, bytes: []const u8) T {
456 if (T.is_signed) {
457 return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes));
502/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
503/// and ignores extra bytes.
504/// Note that @sizeOf(u24) is 3.
505/// The bit count of T must be evenly divisible by 8.
506pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian) T {
507 assert(@sizeOf(u24) == 3);
508 assert(bytes.len >= @sizeOf(T));
509 // TODO https://github.com/ziglang/zig/issues/863
510 return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian);
511}
512
513test "comptime read/write int" {
514 comptime {
515 var bytes: [2]u8 = undefined;
516 std.mem.writeIntLittle(u16, &bytes, 0x1234);
517 const result = std.mem.readIntBig(u16, &bytes);
518 std.debug.assert(result == 0x3412);
458519 }
459 assert(bytes.len == @sizeOf(T));
460 if (T == u8) return bytes[0];
461 var result: T = 0;
462 {
463 comptime var i = 0;
464 inline while (i < @sizeOf(T)) : (i += 1) {
465 result |= T(bytes[i]) << i * 8;
466 }
520 comptime {
521 var bytes: [2]u8 = undefined;
522 std.mem.writeIntBig(u16, &bytes, 0x1234);
523 const result = std.mem.readIntLittle(u16, &bytes);
524 std.debug.assert(result == 0x3412);
467525 }
468 return result;
469526}
470527
471test "readIntBE/LE" {
472 assert(readIntBE(u0, []u8{}) == 0x0);
473 assert(readIntLE(u0, []u8{}) == 0x0);
528test "readIntBig and readIntLittle" {
529 assert(readIntSliceBig(u0, []u8{}) == 0x0);
530 assert(readIntSliceLittle(u0, []u8{}) == 0x0);
474531
475 assert(readIntBE(u8, []u8{0x32}) == 0x32);
476 assert(readIntLE(u8, []u8{0x12}) == 0x12);
532 assert(readIntSliceBig(u8, []u8{0x32}) == 0x32);
533 assert(readIntSliceLittle(u8, []u8{0x12}) == 0x12);
477534
478 assert(readIntBE(u16, []u8{0x12, 0x34}) == 0x1234);
479 assert(readIntLE(u16, []u8{0x12, 0x34}) == 0x3412);
535 assert(readIntSliceBig(u16, []u8{ 0x12, 0x34 }) == 0x1234);
536 assert(readIntSliceLittle(u16, []u8{ 0x12, 0x34 }) == 0x3412);
480537
481 assert(readIntBE(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024);
482 assert(readIntLE(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec);
538 assert(readIntSliceBig(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024);
539 assert(readIntSliceLittle(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec);
483540
484 assert(readIntBE(i8, []u8{0xff}) == -1);
485 assert(readIntLE(i8, []u8{0xfe}) == -2);
541 assert(readIntSliceBig(i8, []u8{0xff}) == -1);
542 assert(readIntSliceLittle(i8, []u8{0xfe}) == -2);
486543
487 assert(readIntBE(i16, []u8{0xff, 0xfd}) == -3);
488 assert(readIntLE(i16, []u8{0xfc, 0xff}) == -4);
544 assert(readIntSliceBig(i16, []u8{ 0xff, 0xfd }) == -3);
545 assert(readIntSliceLittle(i16, []u8{ 0xfc, 0xff }) == -4);
489546}
490547
491/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
492/// to fill the entire buffer provided.
493/// value must be an integer.
494pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
495 const uint = @IntType(false, @typeOf(value).bit_count);
496 var bits = @truncate(uint, value);
497 switch (endian) {
498 builtin.Endian.Big => {
499 var index: usize = buf.len;
500 while (index != 0) {
501 index -= 1;
548/// Writes an integer to memory, storing it in twos-complement.
549/// This function always succeeds, has defined behavior for all inputs, and
550/// accepts any integer bit width.
551/// This function stores in native endian, which means it is implemented as a simple
552/// memory store.
553pub fn writeIntNative(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
554 @ptrCast(*align(1) T, buf).* = value;
555}
502556
503 buf[index] = @truncate(u8, bits);
504 bits >>= 8;
505 }
506 },
507 builtin.Endian.Little => {
508 for (buf) |*b| {
509 b.* = @truncate(u8, bits);
510 bits >>= 8;
511 }
512 },
557/// Writes an integer to memory, storing it in twos-complement.
558/// This function always succeeds, has defined behavior for all inputs, but
559/// the integer bit width must be divisible by 8.
560/// This function stores in foreign endian, which means it does a @bswap first.
561pub fn writeIntForeign(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
562 writeIntNative(T, buf, @bswap(T, value));
563}
564
565pub const writeIntLittle = switch (builtin.endian) {
566 builtin.Endian.Little => writeIntNative,
567 builtin.Endian.Big => writeIntForeign,
568};
569
570pub const writeIntBig = switch (builtin.endian) {
571 builtin.Endian.Little => writeIntForeign,
572 builtin.Endian.Big => writeIntNative,
573};
574
575/// Writes an integer to memory, storing it in twos-complement.
576/// This function always succeeds, has defined behavior for all inputs, but
577/// the integer bit width must be divisible by 8.
578pub fn writeInt(comptime T: type, buffer: *[@sizeOf(T)]u8, value: T, endian: builtin.Endian) void {
579 comptime assert(T.bit_count % 8 == 0);
580 if (endian == builtin.endian) {
581 return writeIntNative(T, buffer, value);
582 } else {
583 return writeIntForeign(T, buffer, value);
513584 }
514 assert(bits == 0);
515585}
516586
517pub fn writeIntBE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
518 assert(T.bit_count % 8 == 0);
587/// Writes a twos-complement little-endian integer to memory.
588/// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
589/// The bit count of T must be divisible by 8.
590/// Any extra bytes in buffer after writing the integer are set to zero. To
591/// avoid the branch to check for extra buffer bytes, use writeIntLittle
592/// instead.
593pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
594 comptime assert(@sizeOf(u24) == 3);
595 comptime assert(T.bit_count % 8 == 0);
596 assert(buffer.len >= @sizeOf(T));
597
598 // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
519599 const uint = @IntType(false, T.bit_count);
520 if (uint == u0) {
521 return;
522 }
523 var bits = @bitCast(uint, value);
524 if (uint == u8) {
525 buf[0] = bits;
526 return;
600 var bits = @truncate(uint, value);
601 for (buffer) |*b| {
602 b.* = @truncate(u8, bits);
603 bits >>= 8;
527604 }
528 var index: usize = buf.len;
605}
606
607/// Writes a twos-complement big-endian integer to memory.
608/// Asserts that buffer.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
609/// The bit count of T must be divisible by 8.
610/// Any extra bytes in buffer before writing the integer are set to zero. To
611/// avoid the branch to check for extra buffer bytes, use writeIntBig instead.
612pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
613 comptime assert(@sizeOf(u24) == 3);
614 comptime assert(T.bit_count % 8 == 0);
615 assert(buffer.len >= @sizeOf(T));
616
617 // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
618 const uint = @IntType(false, T.bit_count);
619 var bits = @truncate(uint, value);
620 var index: usize = buffer.len;
529621 while (index != 0) {
530622 index -= 1;
531
532 buf[index] = @truncate(u8, bits);
623 buffer[index] = @truncate(u8, bits);
533624 bits >>= 8;
534625 }
535 assert(bits == 0);
536626}
537627
538pub fn writeIntLE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
539 assert(T.bit_count % 8 == 0);
540 const uint = @IntType(false, T.bit_count);
541 if (uint == u0) {
542 return;
543 }
544 var bits = @bitCast(uint, value);
545 if (uint == u8) {
546 buf[0] = bits;
547 return;
548 }
549 // FIXME: this should just be for (buf).
550 // See https://github.com/ziglang/zig/issues/1663
551 for (buf.*) |*b| {
552 b.* = @truncate(u8, bits);
553 bits >>= 8;
628pub const writeIntSliceNative = switch (builtin.endian) {
629 builtin.Endian.Little => writeIntSliceLittle,
630 builtin.Endian.Big => writeIntSliceBig,
631};
632
633pub const writeIntSliceForeign = switch (builtin.endian) {
634 builtin.Endian.Little => writeIntSliceBig,
635 builtin.Endian.Big => writeIntSliceLittle,
636};
637
638/// Writes a twos-complement integer to memory, with the specified endianness.
639/// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
640/// The bit count of T must be evenly divisible by 8.
641/// Any extra bytes in buffer not part of the integer are set to zero, with
642/// respect to endianness. To avoid the branch to check for extra buffer bytes,
643/// use writeInt instead.
644pub fn writeIntSlice(comptime T: type, buffer: []u8, value: T, endian: builtin.Endian) void {
645 comptime assert(T.bit_count % 8 == 0);
646 switch (endian) {
647 builtin.Endian.Little => return writeIntSliceLittle(T, buffer, value),
648 builtin.Endian.Big => return writeIntSliceBig(T, buffer, value),
554649 }
555 assert(bits == 0);
556650}
557651
558test "writeIntBE/LE" {
652test "writeIntBig and writeIntLittle" {
559653 var buf0: [0]u8 = undefined;
560654 var buf1: [1]u8 = undefined;
561655 var buf2: [2]u8 = undefined;
562656 var buf9: [9]u8 = undefined;
563657
564 writeIntBE(u0, &buf0, 0x0);
658 writeIntBig(u0, &buf0, 0x0);
565659 assert(eql_slice_u8(buf0[0..], []u8{}));
566 writeIntLE(u0, &buf0, 0x0);
660 writeIntLittle(u0, &buf0, 0x0);
567661 assert(eql_slice_u8(buf0[0..], []u8{}));
568662
569 writeIntBE(u8, &buf1, 0x12);
663 writeIntBig(u8, &buf1, 0x12);
570664 assert(eql_slice_u8(buf1[0..], []u8{0x12}));
571 writeIntLE(u8, &buf1, 0x34);
665 writeIntLittle(u8, &buf1, 0x34);
572666 assert(eql_slice_u8(buf1[0..], []u8{0x34}));
573667
574 writeIntBE(u16, &buf2, 0x1234);
668 writeIntBig(u16, &buf2, 0x1234);
575669 assert(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 }));
576 writeIntLE(u16, &buf2, 0x5678);
670 writeIntLittle(u16, &buf2, 0x5678);
577671 assert(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 }));
578672
579 writeIntBE(u72, &buf9, 0x123456789abcdef024);
673 writeIntBig(u72, &buf9, 0x123456789abcdef024);
580674 assert(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }));
581 writeIntLE(u72, &buf9, 0xfedcba9876543210ec);
675 writeIntLittle(u72, &buf9, 0xfedcba9876543210ec);
582676 assert(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }));
583677
584 writeIntBE(i8, &buf1, -1);
678 writeIntBig(i8, &buf1, -1);
585679 assert(eql_slice_u8(buf1[0..], []u8{0xff}));
586 writeIntLE(i8, &buf1, -2);
680 writeIntLittle(i8, &buf1, -2);
587681 assert(eql_slice_u8(buf1[0..], []u8{0xfe}));
588682
589 writeIntBE(i16, &buf2, -3);
683 writeIntBig(i16, &buf2, -3);
590684 assert(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd }));
591 writeIntLE(i16, &buf2, -4);
685 writeIntLittle(i16, &buf2, -4);
592686 assert(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff }));
593687}
594688
......@@ -737,12 +831,12 @@ fn testReadIntImpl() void {
737831 0x56,
738832 0x78,
739833 };
740 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
741 assert(readIntBE(u32, bytes) == 0x12345678);
742 assert(readIntBE(i32, bytes) == 0x12345678);
743 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);
744 assert(readIntLE(u32, bytes) == 0x78563412);
745 assert(readIntLE(i32, bytes) == 0x78563412);
834 assert(readInt(u32, &bytes, builtin.Endian.Big) == 0x12345678);
835 assert(readIntBig(u32, &bytes) == 0x12345678);
836 assert(readIntBig(i32, &bytes) == 0x12345678);
837 assert(readInt(u32, &bytes, builtin.Endian.Little) == 0x78563412);
838 assert(readIntLittle(u32, &bytes) == 0x78563412);
839 assert(readIntLittle(i32, &bytes) == 0x78563412);
746840 }
747841 {
748842 const buf = []u8{
......@@ -751,7 +845,7 @@ fn testReadIntImpl() void {
751845 0x12,
752846 0x34,
753847 };
754 const answer = readInt(buf, u64, builtin.Endian.Big);
848 const answer = readInt(u32, &buf, builtin.Endian.Big);
755849 assert(answer == 0x00001234);
756850 }
757851 {
......@@ -761,7 +855,7 @@ fn testReadIntImpl() void {
761855 0x00,
762856 0x00,
763857 };
764 const answer = readInt(buf, u64, builtin.Endian.Little);
858 const answer = readInt(u32, &buf, builtin.Endian.Little);
765859 assert(answer == 0x00003412);
766860 }
767861 {
......@@ -769,21 +863,33 @@ fn testReadIntImpl() void {
769863 0xff,
770864 0xfe,
771865 };
772 assert(readIntBE(u16, bytes) == 0xfffe);
773 assert(readIntBE(i16, bytes) == -0x0002);
774 assert(readIntLE(u16, bytes) == 0xfeff);
775 assert(readIntLE(i16, bytes) == -0x0101);
866 assert(readIntBig(u16, &bytes) == 0xfffe);
867 assert(readIntBig(i16, &bytes) == -0x0002);
868 assert(readIntLittle(u16, &bytes) == 0xfeff);
869 assert(readIntLittle(i16, &bytes) == -0x0101);
776870 }
777871}
778872
779test "testWriteInt" {
873test "std.mem.writeIntSlice" {
780874 testWriteIntImpl();
781875 comptime testWriteIntImpl();
782876}
783877fn testWriteIntImpl() void {
784878 var bytes: [8]u8 = undefined;
785879
786 writeInt(bytes[0..], u64(0x12345678CAFEBABE), builtin.Endian.Big);
880 writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Big);
881 assert(eql(u8, bytes, []u8{
882 0x00, 0x00, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x00,
884 }));
885
886 writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Little);
887 assert(eql(u8, bytes, []u8{
888 0x00, 0x00, 0x00, 0x00,
889 0x00, 0x00, 0x00, 0x00,
890 }));
891
892 writeIntSlice(u64, bytes[0..], 0x12345678CAFEBABE, builtin.Endian.Big);
787893 assert(eql(u8, bytes, []u8{
788894 0x12,
789895 0x34,
......@@ -795,7 +901,7 @@ fn testWriteIntImpl() void {
795901 0xBE,
796902 }));
797903
798 writeInt(bytes[0..], u64(0xBEBAFECA78563412), builtin.Endian.Little);
904 writeIntSlice(u64, bytes[0..], 0xBEBAFECA78563412, builtin.Endian.Little);
799905 assert(eql(u8, bytes, []u8{
800906 0x12,
801907 0x34,
......@@ -807,7 +913,7 @@ fn testWriteIntImpl() void {
807913 0xBE,
808914 }));
809915
810 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
916 writeIntSlice(u32, bytes[0..], 0x12345678, builtin.Endian.Big);
811917 assert(eql(u8, bytes, []u8{
812918 0x00,
813919 0x00,
......@@ -819,7 +925,7 @@ fn testWriteIntImpl() void {
819925 0x78,
820926 }));
821927
822 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);
928 writeIntSlice(u32, bytes[0..], 0x78563412, builtin.Endian.Little);
823929 assert(eql(u8, bytes, []u8{
824930 0x12,
825931 0x34,
......@@ -831,7 +937,7 @@ fn testWriteIntImpl() void {
831937 0x00,
832938 }));
833939
834 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);
940 writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Big);
835941 assert(eql(u8, bytes, []u8{
836942 0x00,
837943 0x00,
......@@ -843,7 +949,7 @@ fn testWriteIntImpl() void {
843949 0x34,
844950 }));
845951
846 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);
952 writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Little);
847953 assert(eql(u8, bytes, []u8{
848954 0x34,
849955 0x12,
......@@ -941,29 +1047,52 @@ test "std.mem.rotate" {
9411047 }));
9421048}
9431049
944// TODO: When https://github.com/ziglang/zig/issues/649 is solved these can be done by
945// endian-casting the pointer and then dereferencing
1050/// Converts a little-endian integer to host endianness.
1051pub fn littleToNative(comptime T: type, x: T) T {
1052 return switch (builtin.endian) {
1053 builtin.Endian.Little => x,
1054 builtin.Endian.Big => @bswap(T, x),
1055 };
1056}
9461057
947pub fn endianSwapIfLe(comptime T: type, x: T) T {
948 return endianSwapIf(builtin.Endian.Little, T, x);
1058/// Converts a big-endian integer to host endianness.
1059pub fn bigToNative(comptime T: type, x: T) T {
1060 return switch (builtin.endian) {
1061 builtin.Endian.Little => @bswap(T, x),
1062 builtin.Endian.Big => x,
1063 };
9491064}
9501065
951pub fn endianSwapIfBe(comptime T: type, x: T) T {
952 return endianSwapIf(builtin.Endian.Big, T, x);
1066/// Converts an integer from specified endianness to host endianness.
1067pub fn toNative(comptime T: type, x: T, endianness_of_x: builtin.Endian) T {
1068 return switch (endianness_of_x) {
1069 builtin.Endian.Little => littleToNative(T, x),
1070 builtin.Endian.Big => bigToNative(T, x),
1071 };
9531072}
9541073
955pub fn endianSwapIf(endian: builtin.Endian, comptime T: type, x: T) T {
956 return if (builtin.endian == endian) endianSwap(T, x) else x;
1074/// Converts an integer which has host endianness to the desired endianness.
1075pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T {
1076 return switch (desired_endianness) {
1077 builtin.Endian.Little => nativeToLittle(T, x),
1078 builtin.Endian.Big => nativeToBig(T, x),
1079 };
9571080}
9581081
959pub fn endianSwap(comptime T: type, x: T) T {
960 var buf: [@sizeOf(T)]u8 = undefined;
961 mem.writeInt(buf[0..], x, builtin.Endian.Little);
962 return mem.readInt(buf, T, builtin.Endian.Big);
1082/// Converts an integer which has host endianness to little endian.
1083pub fn nativeToLittle(comptime T: type, x: T) T {
1084 return switch (builtin.endian) {
1085 builtin.Endian.Little => x,
1086 builtin.Endian.Big => @bswap(T, x),
1087 };
9631088}
9641089
965test "std.mem.endianSwap" {
966 assert(endianSwap(u32, 0xDEADBEEF) == 0xEFBEADDE);
1090/// Converts an integer which has host endianness to big endian.
1091pub fn nativeToBig(comptime T: type, x: T) T {
1092 return switch (builtin.endian) {
1093 builtin.Endian.Little => @bswap(T, x),
1094 builtin.Endian.Big => x,
1095 };
9671096}
9681097
9691098fn AsBytesReturnType(comptime P: type) type {
std/meta/index.zig+48
......@@ -76,6 +76,25 @@ test "std.meta.tagName" {
7676 debug.assert(mem.eql(u8, tagName(u2b), "D"));
7777}
7878
79pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
80 inline for (@typeInfo(T).Enum.fields) |enumField| {
81 if (std.mem.eql(u8, str, enumField.name)) {
82 return @field(T, enumField.name);
83 }
84 }
85 return null;
86}
87
88test "std.meta.stringToEnum" {
89 const E1 = enum {
90 A,
91 B,
92 };
93 debug.assert(E1.A == stringToEnum(E1, "A").?);
94 debug.assert(E1.B == stringToEnum(E1, "B").?);
95 debug.assert(null == stringToEnum(E1, "C"));
96}
97
7998pub fn bitCount(comptime T: type) u32 {
8099 return switch (@typeInfo(T)) {
81100 TypeId.Int => |info| info.bits,
......@@ -483,3 +502,32 @@ test "std.meta.eql" {
483502 debug.assert(eql(EU.tst(false), EU.tst(false)));
484503 debug.assert(!eql(EU.tst(false), EU.tst(true)));
485504}
505
506test "intToEnum with error return" {
507 const E1 = enum {
508 A,
509 };
510 const E2 = enum {
511 A,
512 B,
513 };
514
515 var zero: u8 = 0;
516 var one: u16 = 1;
517 debug.assert(intToEnum(E1, zero) catch unreachable == E1.A);
518 debug.assert(intToEnum(E2, one) catch unreachable == E2.B);
519 debug.assertError(intToEnum(E1, one), error.InvalidEnumTag);
520}
521
522pub const IntToEnumError = error{InvalidEnumTag};
523
524pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag {
525 comptime var i = 0;
526 inline while (i != @memberCount(Tag)) : (i += 1) {
527 const this_tag_value = @field(Tag, @memberName(Tag, i));
528 if (tag_int == @enumToInt(this_tag_value)) {
529 return this_tag_value;
530 }
531 }
532 return error.InvalidEnumTag;
533}
std/net.zig+6-6
......@@ -23,7 +23,7 @@ pub const Address = struct {
2323 .os_addr = posix.sockaddr{
2424 .in = posix.sockaddr_in{
2525 .family = posix.AF_INET,
26 .port = std.mem.endianSwapIfLe(u16, _port),
26 .port = mem.nativeToBig(u16, _port),
2727 .addr = ip4,
2828 .zero = []u8{0} ** 8,
2929 },
......@@ -37,7 +37,7 @@ pub const Address = struct {
3737 .os_addr = posix.sockaddr{
3838 .in6 = posix.sockaddr_in6{
3939 .family = posix.AF_INET6,
40 .port = std.mem.endianSwapIfLe(u16, _port),
40 .port = mem.nativeToBig(u16, _port),
4141 .flowinfo = 0,
4242 .addr = ip6.addr,
4343 .scope_id = ip6.scope_id,
......@@ -47,7 +47,7 @@ pub const Address = struct {
4747 }
4848
4949 pub fn port(self: Address) u16 {
50 return std.mem.endianSwapIfLe(u16, self.os_addr.in.port);
50 return mem.bigToNative(u16, self.os_addr.in.port);
5151 }
5252
5353 pub fn initPosix(addr: posix.sockaddr) Address {
......@@ -57,12 +57,12 @@ pub const Address = struct {
5757 pub fn format(self: *const Address, out_stream: var) !void {
5858 switch (self.os_addr.in.family) {
5959 posix.AF_INET => {
60 const native_endian_port = std.mem.endianSwapIfLe(u16, self.os_addr.in.port);
60 const native_endian_port = mem.bigToNative(u16, self.os_addr.in.port);
6161 const bytes = ([]const u8)((*self.os_addr.in.addr)[0..1]);
6262 try out_stream.print("{}.{}.{}.{}:{}", bytes[0], bytes[1], bytes[2], bytes[3], native_endian_port);
6363 },
6464 posix.AF_INET6 => {
65 const native_endian_port = std.mem.endianSwapIfLe(u16, self.os_addr.in6.port);
65 const native_endian_port = mem.bigToNative(u16, self.os_addr.in6.port);
6666 try out_stream.print("[TODO render ip6 address]:{}", native_endian_port);
6767 },
6868 else => try out_stream.write("(unrecognized address family)"),
......@@ -193,7 +193,7 @@ pub fn parseIp6(buf: []const u8) !Ip6Addr {
193193}
194194
195195test "std.net.parseIp4" {
196 assert((try parseIp4("127.0.0.1")) == std.mem.endianSwapIfLe(u32, 0x7f000001));
196 assert((try parseIp4("127.0.0.1")) == mem.bigToNative(u32, 0x7f000001));
197197
198198 testParseIp4Fail("256.0.0.1", error.Overflow);
199199 testParseIp4Fail("x.0.0.1", error.InvalidCharacter);
std/os/child_process.zig+15-2
......@@ -390,6 +390,19 @@ pub const ChildProcess = struct {
390390 setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
391391 setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
392392
393 if (self.stdin_behavior == StdIo.Pipe) {
394 os.close(stdin_pipe[0]);
395 os.close(stdin_pipe[1]);
396 }
397 if (self.stdout_behavior == StdIo.Pipe) {
398 os.close(stdout_pipe[0]);
399 os.close(stdout_pipe[1]);
400 }
401 if (self.stderr_behavior == StdIo.Pipe) {
402 os.close(stderr_pipe[0]);
403 os.close(stderr_pipe[1]);
404 }
405
393406 if (self.cwd) |cwd| {
394407 os.changeCurDir(self.allocator, cwd) catch |err| forkChildErrReport(err_pipe[1], err);
395408 }
......@@ -794,10 +807,10 @@ const ErrInt = @IntType(false, @sizeOf(anyerror) * 8);
794807
795808fn writeIntFd(fd: i32, value: ErrInt) !void {
796809 const stream = &os.File.openHandle(fd).outStream().stream;
797 stream.writeIntNe(ErrInt, value) catch return error.SystemResources;
810 stream.writeIntNative(ErrInt, value) catch return error.SystemResources;
798811}
799812
800813fn readIntFd(fd: i32) !ErrInt {
801814 const stream = &os.File.openHandle(fd).inStream().stream;
802 return stream.readIntNe(ErrInt) catch return error.SystemResources;
815 return stream.readIntNative(ErrInt) catch return error.SystemResources;
803816}
std/os/file.zig+62-8
......@@ -228,9 +228,16 @@ pub const File = struct {
228228 return os.isTty(self.handle);
229229 }
230230
231 pub fn seekForward(self: File, amount: isize) !void {
231 pub const SeekError = error{
232 /// TODO make this error impossible to get
233 Overflow,
234 Unseekable,
235 Unexpected,
236 };
237
238 pub fn seekForward(self: File, amount: isize) SeekError!void {
232239 switch (builtin.os) {
233 Os.linux, Os.macosx, Os.ios => {
240 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
234241 const result = posix.lseek(self.handle, amount, posix.SEEK_CUR);
235242 const err = posix.getErrno(result);
236243 if (err > 0) {
......@@ -259,9 +266,9 @@ pub const File = struct {
259266 }
260267 }
261268
262 pub fn seekTo(self: File, pos: usize) !void {
269 pub fn seekTo(self: File, pos: usize) SeekError!void {
263270 switch (builtin.os) {
264 Os.linux, Os.macosx, Os.ios => {
271 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
265272 const ipos = try math.cast(isize, pos);
266273 const result = posix.lseek(self.handle, ipos, posix.SEEK_SET);
267274 const err = posix.getErrno(result);
......@@ -293,9 +300,16 @@ pub const File = struct {
293300 }
294301 }
295302
296 pub fn getPos(self: File) !usize {
303 pub const GetSeekPosError = error{
304 Overflow,
305 SystemResources,
306 Unseekable,
307 Unexpected,
308 };
309
310 pub fn getPos(self: File) GetSeekPosError!usize {
297311 switch (builtin.os) {
298 Os.linux, Os.macosx, Os.ios => {
312 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
299313 const result = posix.lseek(self.handle, 0, posix.SEEK_CUR);
300314 const err = posix.getErrno(result);
301315 if (err > 0) {
......@@ -323,13 +337,13 @@ pub const File = struct {
323337 }
324338
325339 assert(pos >= 0);
326 return math.cast(usize, pos) catch error.FilePosLargerThanPointerRange;
340 return math.cast(usize, pos);
327341 },
328342 else => @compileError("unsupported OS"),
329343 }
330344 }
331345
332 pub fn getEndPos(self: File) !usize {
346 pub fn getEndPos(self: File) GetSeekPosError!usize {
333347 if (is_posix) {
334348 const stat = try os.posixFStat(self.handle);
335349 return @intCast(usize, stat.size);
......@@ -431,6 +445,18 @@ pub const File = struct {
431445 };
432446 }
433447
448 pub fn seekableStream(file: File) SeekableStream {
449 return SeekableStream{
450 .file = file,
451 .stream = SeekableStream.Stream{
452 .seekToFn = SeekableStream.seekToFn,
453 .seekForwardFn = SeekableStream.seekForwardFn,
454 .getPosFn = SeekableStream.getPosFn,
455 .getEndPosFn = SeekableStream.getEndPosFn,
456 },
457 };
458 }
459
434460 /// Implementation of io.InStream trait for File
435461 pub const InStream = struct {
436462 file: File,
......@@ -458,4 +484,32 @@ pub const File = struct {
458484 return self.file.write(bytes);
459485 }
460486 };
487
488 /// Implementation of io.SeekableStream trait for File
489 pub const SeekableStream = struct {
490 file: File,
491 stream: Stream,
492
493 pub const Stream = io.SeekableStream(SeekError, GetSeekPosError);
494
495 pub fn seekToFn(seekable_stream: *Stream, pos: usize) SeekError!void {
496 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
497 return self.file.seekTo(pos);
498 }
499
500 pub fn seekForwardFn(seekable_stream: *Stream, amt: isize) SeekError!void {
501 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
502 return self.file.seekForward(amt);
503 }
504
505 pub fn getEndPosFn(seekable_stream: *Stream) GetSeekPosError!usize {
506 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
507 return self.file.getEndPos();
508 }
509
510 pub fn getPosFn(seekable_stream: *Stream) GetSeekPosError!usize {
511 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
512 return self.file.getPos();
513 }
514 };
461515};
std/os/freebsd/errno.zig created+121
......@@ -0,0 +1,121 @@
1pub const EPERM = 1; // Operation not permitted
2pub const ENOENT = 2; // No such file or directory
3pub const ESRCH = 3; // No such process
4pub const EINTR = 4; // Interrupted system call
5pub const EIO = 5; // Input/output error
6pub const ENXIO = 6; // Device not configured
7pub const E2BIG = 7; // Argument list too long
8pub const ENOEXEC = 8; // Exec format error
9pub const EBADF = 9; // Bad file descriptor
10pub const ECHILD = 10; // No child processes
11pub const EDEADLK = 11; // Resource deadlock avoided
12// 11 was EAGAIN
13pub const ENOMEM = 12; // Cannot allocate memory
14pub const EACCES = 13; // Permission denied
15pub const EFAULT = 14; // Bad address
16pub const ENOTBLK = 15; // Block device required
17pub const EBUSY = 16; // Device busy
18pub const EEXIST = 17; // File exists
19pub const EXDEV = 18; // Cross-device link
20pub const ENODEV = 19; // Operation not supported by device
21pub const ENOTDIR = 20; // Not a directory
22pub const EISDIR = 21; // Is a directory
23pub const EINVAL = 22; // Invalid argument
24pub const ENFILE = 23; // Too many open files in system
25pub const EMFILE = 24; // Too many open files
26pub const ENOTTY = 25; // Inappropriate ioctl for device
27pub const ETXTBSY = 26; // Text file busy
28pub const EFBIG = 27; // File too large
29pub const ENOSPC = 28; // No space left on device
30pub const ESPIPE = 29; // Illegal seek
31pub const EROFS = 30; // Read-only filesystem
32pub const EMLINK = 31; // Too many links
33pub const EPIPE = 32; // Broken pipe
34
35// math software
36pub const EDOM = 33; // Numerical argument out of domain
37pub const ERANGE = 34; // Result too large
38
39// non-blocking and interrupt i/o
40pub const EAGAIN = 35; // Resource temporarily unavailable
41pub const EWOULDBLOCK = EAGAIN; // Operation would block
42pub const EINPROGRESS = 36; // Operation now in progress
43pub const EALREADY = 37; // Operation already in progress
44
45// ipc/network software -- argument errors
46pub const ENOTSOCK = 38; // Socket operation on non-socket
47pub const EDESTADDRREQ = 39; // Destination address required
48pub const EMSGSIZE = 40; // Message too long
49pub const EPROTOTYPE = 41; // Protocol wrong type for socket
50pub const ENOPROTOOPT = 42; // Protocol not available
51pub const EPROTONOSUPPORT = 43; // Protocol not supported
52pub const ESOCKTNOSUPPORT = 44; // Socket type not supported
53pub const EOPNOTSUPP = 45; // Operation not supported
54pub const ENOTSUP = EOPNOTSUPP; // Operation not supported
55pub const EPFNOSUPPORT = 46; // Protocol family not supported
56pub const EAFNOSUPPORT = 47; // Address family not supported by protocol family
57pub const EADDRINUSE = 48; // Address already in use
58pub const EADDRNOTAVAIL = 49; // Can't assign requested address
59
60// ipc/network software -- operational errors
61pub const ENETDOWN = 50; // Network is down
62pub const ENETUNREACH = 51; // Network is unreachable
63pub const ENETRESET = 52; // Network dropped connection on reset
64pub const ECONNABORTED = 53; // Software caused connection abort
65pub const ECONNRESET = 54; // Connection reset by peer
66pub const ENOBUFS = 55; // No buffer space available
67pub const EISCONN = 56; // Socket is already connected
68pub const ENOTCONN = 57; // Socket is not connected
69pub const ESHUTDOWN = 58; // Can't send after socket shutdown
70pub const ETOOMANYREFS = 59; // Too many references: can't splice
71pub const ETIMEDOUT = 60; // Operation timed out
72pub const ECONNREFUSED = 61; // Connection refused
73
74pub const ELOOP = 62; // Too many levels of symbolic links
75pub const ENAMETOOLONG = 63; // File name too long
76
77// should be rearranged
78pub const EHOSTDOWN = 64; // Host is down
79pub const EHOSTUNREACH = 65; // No route to host
80pub const ENOTEMPTY = 66; // Directory not empty
81
82// quotas & mush
83pub const EPROCLIM = 67; // Too many processes
84pub const EUSERS = 68; // Too many users
85pub const EDQUOT = 69; // Disc quota exceeded
86
87// Network File System
88pub const ESTALE = 70; // Stale NFS file handle
89pub const EREMOTE = 71; // Too many levels of remote in path
90pub const EBADRPC = 72; // RPC struct is bad
91pub const ERPCMISMATCH = 73; // RPC version wrong
92pub const EPROGUNAVAIL = 74; // RPC prog. not avail
93pub const EPROGMISMATCH = 75; // Program version wrong
94pub const EPROCUNAVAIL = 76; // Bad procedure for program
95
96pub const ENOLCK = 77; // No locks available
97pub const ENOSYS = 78; // Function not implemented
98
99pub const EFTYPE = 79; // Inappropriate file type or format
100pub const EAUTH = 80; // Authentication error
101pub const ENEEDAUTH = 81; // Need authenticator
102pub const EIDRM = 82; // Identifier removed
103pub const ENOMSG = 83; // No message of desired type
104pub const EOVERFLOW = 84; // Value too large to be stored in data type
105pub const ECANCELED = 85; // Operation canceled
106pub const EILSEQ = 86; // Illegal byte sequence
107pub const ENOATTR = 87; // Attribute not found
108
109pub const EDOOFUS = 88; // Programming error
110
111pub const EBADMSG = 89; // Bad message
112pub const EMULTIHOP = 90; // Multihop attempted
113pub const ENOLINK = 91; // Link has been severed
114pub const EPROTO = 92; // Protocol error
115
116pub const ENOTCAPABLE = 93; // Capabilities insufficient
117pub const ECAPMODE = 94; // Not permitted in capability mode
118pub const ENOTRECOVERABLE = 95; // State not recoverable
119pub const EOWNERDEAD = 96; // Previous owner died
120
121pub const ELAST = 96; // Must be equal largest errno
std/os/freebsd/index.zig created+801
......@@ -0,0 +1,801 @@
1const assert = @import("../debug.zig").assert;
2const builtin = @import("builtin");
3const arch = switch (builtin.arch) {
4 builtin.Arch.x86_64 => @import("x86_64.zig"),
5 else => @compileError("unsupported arch"),
6};
7pub use @import("syscall.zig");
8pub use @import("errno.zig");
9
10const std = @import("../../index.zig");
11const c = std.c;
12const maxInt = std.math.maxInt;
13pub const Kevent = c.Kevent;
14
15pub const PATH_MAX = 1024;
16
17pub const STDIN_FILENO = 0;
18pub const STDOUT_FILENO = 1;
19pub const STDERR_FILENO = 2;
20
21pub const PROT_NONE = 0;
22pub const PROT_READ = 1;
23pub const PROT_WRITE = 2;
24pub const PROT_EXEC = 4;
25
26pub const MAP_FAILED = maxInt(usize);
27pub const MAP_SHARED = 0x0001;
28pub const MAP_PRIVATE = 0x0002;
29pub const MAP_FIXED = 0x0010;
30pub const MAP_STACK = 0x0400;
31pub const MAP_NOSYNC = 0x0800;
32pub const MAP_ANON = 0x1000;
33pub const MAP_ANONYMOUS = MAP_ANON;
34pub const MAP_FILE = 0;
35pub const MAP_NORESERVE = 0;
36
37pub const MAP_GUARD = 0x00002000;
38pub const MAP_EXCL = 0x00004000;
39pub const MAP_NOCORE = 0x00020000;
40pub const MAP_PREFAULT_READ = 0x00040000;
41pub const MAP_32BIT = 0x00080000;
42
43pub const WNOHANG = 1;
44pub const WUNTRACED = 2;
45pub const WSTOPPED = WUNTRACED;
46pub const WCONTINUED = 4;
47pub const WNOWAIT = 8;
48pub const WEXITED = 16;
49pub const WTRAPPED = 32;
50
51pub const SA_ONSTACK = 0x0001;
52pub const SA_RESTART = 0x0002;
53pub const SA_RESETHAND = 0x0004;
54pub const SA_NOCLDSTOP = 0x0008;
55pub const SA_NODEFER = 0x0010;
56pub const SA_NOCLDWAIT = 0x0020;
57pub const SA_SIGINFO = 0x0040;
58
59pub const SIGHUP = 1;
60pub const SIGINT = 2;
61pub const SIGQUIT = 3;
62pub const SIGILL = 4;
63pub const SIGTRAP = 5;
64pub const SIGABRT = 6;
65pub const SIGIOT = SIGABRT;
66pub const SIGEMT = 7;
67pub const SIGFPE = 8;
68pub const SIGKILL = 9;
69pub const SIGBUS = 10;
70pub const SIGSEGV = 11;
71pub const SIGSYS = 12;
72pub const SIGPIPE = 13;
73pub const SIGALRM = 14;
74pub const SIGTERM = 15;
75pub const SIGURG = 16;
76pub const SIGSTOP = 17;
77pub const SIGTSTP = 18;
78pub const SIGCONT = 19;
79pub const SIGCHLD = 20;
80pub const SIGTTIN = 21;
81pub const SIGTTOU = 22;
82pub const SIGIO = 23;
83pub const SIGXCPU = 24;
84pub const SIGXFSZ = 25;
85pub const SIGVTALRM = 26;
86pub const SIGPROF = 27;
87pub const SIGWINCH = 28;
88pub const SIGINFO = 29;
89pub const SIGUSR1 = 30;
90pub const SIGUSR2 = 31;
91pub const SIGTHR = 32;
92pub const SIGLWP = SIGTHR;
93pub const SIGLIBRT = 33;
94
95pub const SIGRTMIN = 65;
96pub const SIGRTMAX = 126;
97
98pub const O_RDONLY = 0o0;
99pub const O_WRONLY = 0o1;
100pub const O_RDWR = 0o2;
101pub const O_ACCMODE = 0o3;
102
103pub const O_CREAT = 0o100;
104pub const O_EXCL = 0o200;
105pub const O_NOCTTY = 0o400;
106pub const O_TRUNC = 0o1000;
107pub const O_APPEND = 0o2000;
108pub const O_NONBLOCK = 0o4000;
109pub const O_DSYNC = 0o10000;
110pub const O_SYNC = 0o4010000;
111pub const O_RSYNC = 0o4010000;
112pub const O_DIRECTORY = 0o200000;
113pub const O_NOFOLLOW = 0o400000;
114pub const O_CLOEXEC = 0o2000000;
115
116pub const O_ASYNC = 0o20000;
117pub const O_DIRECT = 0o40000;
118pub const O_LARGEFILE = 0;
119pub const O_NOATIME = 0o1000000;
120pub const O_PATH = 0o10000000;
121pub const O_TMPFILE = 0o20200000;
122pub const O_NDELAY = O_NONBLOCK;
123
124pub const F_DUPFD = 0;
125pub const F_GETFD = 1;
126pub const F_SETFD = 2;
127pub const F_GETFL = 3;
128pub const F_SETFL = 4;
129
130pub const F_SETOWN = 8;
131pub const F_GETOWN = 9;
132pub const F_SETSIG = 10;
133pub const F_GETSIG = 11;
134
135pub const F_GETLK = 5;
136pub const F_SETLK = 6;
137pub const F_SETLKW = 7;
138
139pub const F_SETOWN_EX = 15;
140pub const F_GETOWN_EX = 16;
141
142pub const F_GETOWNER_UIDS = 17;
143
144pub const SEEK_SET = 0;
145pub const SEEK_CUR = 1;
146pub const SEEK_END = 2;
147
148pub const SIG_BLOCK = 1;
149pub const SIG_UNBLOCK = 2;
150pub const SIG_SETMASK = 3;
151
152pub const SOCK_STREAM = 1;
153pub const SOCK_DGRAM = 2;
154pub const SOCK_RAW = 3;
155pub const SOCK_RDM = 4;
156pub const SOCK_SEQPACKET = 5;
157
158pub const SOCK_CLOEXEC = 0x10000000;
159pub const SOCK_NONBLOCK = 0x20000000;
160
161pub const PROTO_ip = 0o000;
162pub const PROTO_icmp = 0o001;
163pub const PROTO_igmp = 0o002;
164pub const PROTO_ggp = 0o003;
165pub const PROTO_ipencap = 0o004;
166pub const PROTO_st = 0o005;
167pub const PROTO_tcp = 0o006;
168pub const PROTO_egp = 0o010;
169pub const PROTO_pup = 0o014;
170pub const PROTO_udp = 0o021;
171pub const PROTO_hmp = 0o024;
172pub const PROTO_xns_idp = 0o026;
173pub const PROTO_rdp = 0o033;
174pub const PROTO_iso_tp4 = 0o035;
175pub const PROTO_xtp = 0o044;
176pub const PROTO_ddp = 0o045;
177pub const PROTO_idpr_cmtp = 0o046;
178pub const PROTO_ipv6 = 0o051;
179pub const PROTO_ipv6_route = 0o053;
180pub const PROTO_ipv6_frag = 0o054;
181pub const PROTO_idrp = 0o055;
182pub const PROTO_rsvp = 0o056;
183pub const PROTO_gre = 0o057;
184pub const PROTO_esp = 0o062;
185pub const PROTO_ah = 0o063;
186pub const PROTO_skip = 0o071;
187pub const PROTO_ipv6_icmp = 0o072;
188pub const PROTO_ipv6_nonxt = 0o073;
189pub const PROTO_ipv6_opts = 0o074;
190pub const PROTO_rspf = 0o111;
191pub const PROTO_vmtp = 0o121;
192pub const PROTO_ospf = 0o131;
193pub const PROTO_ipip = 0o136;
194pub const PROTO_encap = 0o142;
195pub const PROTO_pim = 0o147;
196pub const PROTO_raw = 0o377;
197
198pub const PF_UNSPEC = 0;
199pub const PF_LOCAL = 1;
200pub const PF_UNIX = PF_LOCAL;
201pub const PF_FILE = PF_LOCAL;
202pub const PF_INET = 2;
203pub const PF_AX25 = 3;
204pub const PF_IPX = 4;
205pub const PF_APPLETALK = 5;
206pub const PF_NETROM = 6;
207pub const PF_BRIDGE = 7;
208pub const PF_ATMPVC = 8;
209pub const PF_X25 = 9;
210pub const PF_INET6 = 10;
211pub const PF_ROSE = 11;
212pub const PF_DECnet = 12;
213pub const PF_NETBEUI = 13;
214pub const PF_SECURITY = 14;
215pub const PF_KEY = 15;
216pub const PF_NETLINK = 16;
217pub const PF_ROUTE = PF_NETLINK;
218pub const PF_PACKET = 17;
219pub const PF_ASH = 18;
220pub const PF_ECONET = 19;
221pub const PF_ATMSVC = 20;
222pub const PF_RDS = 21;
223pub const PF_SNA = 22;
224pub const PF_IRDA = 23;
225pub const PF_PPPOX = 24;
226pub const PF_WANPIPE = 25;
227pub const PF_LLC = 26;
228pub const PF_IB = 27;
229pub const PF_MPLS = 28;
230pub const PF_CAN = 29;
231pub const PF_TIPC = 30;
232pub const PF_BLUETOOTH = 31;
233pub const PF_IUCV = 32;
234pub const PF_RXRPC = 33;
235pub const PF_ISDN = 34;
236pub const PF_PHONET = 35;
237pub const PF_IEEE802154 = 36;
238pub const PF_CAIF = 37;
239pub const PF_ALG = 38;
240pub const PF_NFC = 39;
241pub const PF_VSOCK = 40;
242pub const PF_MAX = 41;
243
244pub const AF_UNSPEC = PF_UNSPEC;
245pub const AF_LOCAL = PF_LOCAL;
246pub const AF_UNIX = AF_LOCAL;
247pub const AF_FILE = AF_LOCAL;
248pub const AF_INET = PF_INET;
249pub const AF_AX25 = PF_AX25;
250pub const AF_IPX = PF_IPX;
251pub const AF_APPLETALK = PF_APPLETALK;
252pub const AF_NETROM = PF_NETROM;
253pub const AF_BRIDGE = PF_BRIDGE;
254pub const AF_ATMPVC = PF_ATMPVC;
255pub const AF_X25 = PF_X25;
256pub const AF_INET6 = PF_INET6;
257pub const AF_ROSE = PF_ROSE;
258pub const AF_DECnet = PF_DECnet;
259pub const AF_NETBEUI = PF_NETBEUI;
260pub const AF_SECURITY = PF_SECURITY;
261pub const AF_KEY = PF_KEY;
262pub const AF_NETLINK = PF_NETLINK;
263pub const AF_ROUTE = PF_ROUTE;
264pub const AF_PACKET = PF_PACKET;
265pub const AF_ASH = PF_ASH;
266pub const AF_ECONET = PF_ECONET;
267pub const AF_ATMSVC = PF_ATMSVC;
268pub const AF_RDS = PF_RDS;
269pub const AF_SNA = PF_SNA;
270pub const AF_IRDA = PF_IRDA;
271pub const AF_PPPOX = PF_PPPOX;
272pub const AF_WANPIPE = PF_WANPIPE;
273pub const AF_LLC = PF_LLC;
274pub const AF_IB = PF_IB;
275pub const AF_MPLS = PF_MPLS;
276pub const AF_CAN = PF_CAN;
277pub const AF_TIPC = PF_TIPC;
278pub const AF_BLUETOOTH = PF_BLUETOOTH;
279pub const AF_IUCV = PF_IUCV;
280pub const AF_RXRPC = PF_RXRPC;
281pub const AF_ISDN = PF_ISDN;
282pub const AF_PHONET = PF_PHONET;
283pub const AF_IEEE802154 = PF_IEEE802154;
284pub const AF_CAIF = PF_CAIF;
285pub const AF_ALG = PF_ALG;
286pub const AF_NFC = PF_NFC;
287pub const AF_VSOCK = PF_VSOCK;
288pub const AF_MAX = PF_MAX;
289
290pub const DT_UNKNOWN = 0;
291pub const DT_FIFO = 1;
292pub const DT_CHR = 2;
293pub const DT_DIR = 4;
294pub const DT_BLK = 6;
295pub const DT_REG = 8;
296pub const DT_LNK = 10;
297pub const DT_SOCK = 12;
298pub const DT_WHT = 14;
299
300/// add event to kq (implies enable)
301pub const EV_ADD = 0x0001;
302
303/// delete event from kq
304pub const EV_DELETE = 0x0002;
305
306/// enable event
307pub const EV_ENABLE = 0x0004;
308
309/// disable event (not reported)
310pub const EV_DISABLE = 0x0008;
311
312/// only report one occurrence
313pub const EV_ONESHOT = 0x0010;
314
315/// clear event state after reporting
316pub const EV_CLEAR = 0x0020;
317
318/// force immediate event output
319/// ... with or without EV_ERROR
320/// ... use KEVENT_FLAG_ERROR_EVENTS
321/// on syscalls supporting flags
322pub const EV_RECEIPT = 0x0040;
323
324/// disable event after reporting
325pub const EV_DISPATCH = 0x0080;
326
327pub const EVFILT_READ = -1;
328pub const EVFILT_WRITE = -2;
329
330/// attached to aio requests
331pub const EVFILT_AIO = -3;
332
333/// attached to vnodes
334pub const EVFILT_VNODE = -4;
335
336/// attached to struct proc
337pub const EVFILT_PROC = -5;
338
339/// attached to struct proc
340pub const EVFILT_SIGNAL = -6;
341
342/// timers
343pub const EVFILT_TIMER = -7;
344
345/// Process descriptors
346pub const EVFILT_PROCDESC = -8;
347
348/// Filesystem events
349pub const EVFILT_FS = -9;
350
351pub const EVFILT_LIO = -10;
352
353/// User events
354pub const EVFILT_USER = -11;
355
356/// Sendfile events
357pub const EVFILT_SENDFILE = -12;
358
359pub const EVFILT_EMPTY = -13;
360
361/// On input, NOTE_TRIGGER causes the event to be triggered for output.
362pub const NOTE_TRIGGER = 0x01000000;
363
364/// ignore input fflags
365pub const NOTE_FFNOP = 0x00000000;
366
367/// and fflags
368pub const NOTE_FFAND = 0x40000000;
369
370/// or fflags
371pub const NOTE_FFOR = 0x80000000;
372
373/// copy fflags
374pub const NOTE_FFCOPY = 0xc0000000;
375
376/// mask for operations
377pub const NOTE_FFCTRLMASK = 0xc0000000;
378pub const NOTE_FFLAGSMASK = 0x00ffffff;
379
380/// low water mark
381pub const NOTE_LOWAT = 0x00000001;
382
383/// behave like poll()
384pub const NOTE_FILE_POLL = 0x00000002;
385
386/// vnode was removed
387pub const NOTE_DELETE = 0x00000001;
388
389/// data contents changed
390pub const NOTE_WRITE = 0x00000002;
391
392/// size increased
393pub const NOTE_EXTEND = 0x00000004;
394
395/// attributes changed
396pub const NOTE_ATTRIB = 0x00000008;
397
398/// link count changed
399pub const NOTE_LINK = 0x00000010;
400
401/// vnode was renamed
402pub const NOTE_RENAME = 0x00000020;
403
404/// vnode access was revoked
405pub const NOTE_REVOKE = 0x00000040;
406
407/// vnode was opened
408pub const NOTE_OPEN = 0x00000080;
409
410/// file closed, fd did not allow write
411pub const NOTE_CLOSE = 0x00000100;
412
413/// file closed, fd did allow write
414pub const NOTE_CLOSE_WRITE = 0x00000200;
415
416/// file was read
417pub const NOTE_READ = 0x00000400;
418
419/// process exited
420pub const NOTE_EXIT = 0x80000000;
421
422/// process forked
423pub const NOTE_FORK = 0x40000000;
424
425/// process exec'd
426pub const NOTE_EXEC = 0x20000000;
427
428/// mask for signal & exit status
429pub const NOTE_PDATAMASK = 0x000fffff;
430pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
431
432/// data is seconds
433pub const NOTE_SECONDS = 0x00000001;
434
435/// data is milliseconds
436pub const NOTE_MSECONDS = 0x00000002;
437
438/// data is microseconds
439pub const NOTE_USECONDS = 0x00000004;
440
441/// data is nanoseconds
442pub const NOTE_NSECONDS = 0x00000008;
443
444/// timeout is absolute
445pub const NOTE_ABSTIME = 0x00000010;
446
447pub const TCGETS = 0x5401;
448pub const TCSETS = 0x5402;
449pub const TCSETSW = 0x5403;
450pub const TCSETSF = 0x5404;
451pub const TCGETA = 0x5405;
452pub const TCSETA = 0x5406;
453pub const TCSETAW = 0x5407;
454pub const TCSETAF = 0x5408;
455pub const TCSBRK = 0x5409;
456pub const TCXONC = 0x540A;
457pub const TCFLSH = 0x540B;
458pub const TIOCEXCL = 0x540C;
459pub const TIOCNXCL = 0x540D;
460pub const TIOCSCTTY = 0x540E;
461pub const TIOCGPGRP = 0x540F;
462pub const TIOCSPGRP = 0x5410;
463pub const TIOCOUTQ = 0x5411;
464pub const TIOCSTI = 0x5412;
465pub const TIOCGWINSZ = 0x5413;
466pub const TIOCSWINSZ = 0x5414;
467pub const TIOCMGET = 0x5415;
468pub const TIOCMBIS = 0x5416;
469pub const TIOCMBIC = 0x5417;
470pub const TIOCMSET = 0x5418;
471pub const TIOCGSOFTCAR = 0x5419;
472pub const TIOCSSOFTCAR = 0x541A;
473pub const FIONREAD = 0x541B;
474pub const TIOCINQ = FIONREAD;
475pub const TIOCLINUX = 0x541C;
476pub const TIOCCONS = 0x541D;
477pub const TIOCGSERIAL = 0x541E;
478pub const TIOCSSERIAL = 0x541F;
479pub const TIOCPKT = 0x5420;
480pub const FIONBIO = 0x5421;
481pub const TIOCNOTTY = 0x5422;
482pub const TIOCSETD = 0x5423;
483pub const TIOCGETD = 0x5424;
484pub const TCSBRKP = 0x5425;
485pub const TIOCSBRK = 0x5427;
486pub const TIOCCBRK = 0x5428;
487pub const TIOCGSID = 0x5429;
488pub const TIOCGRS485 = 0x542E;
489pub const TIOCSRS485 = 0x542F;
490pub const TIOCGPTN = 0x80045430;
491pub const TIOCSPTLCK = 0x40045431;
492pub const TIOCGDEV = 0x80045432;
493pub const TCGETX = 0x5432;
494pub const TCSETX = 0x5433;
495pub const TCSETXF = 0x5434;
496pub const TCSETXW = 0x5435;
497pub const TIOCSIG = 0x40045436;
498pub const TIOCVHANGUP = 0x5437;
499pub const TIOCGPKT = 0x80045438;
500pub const TIOCGPTLCK = 0x80045439;
501pub const TIOCGEXCL = 0x80045440;
502
503fn unsigned(s: i32) u32 {
504 return @bitCast(u32, s);
505}
506fn signed(s: u32) i32 {
507 return @bitCast(i32, s);
508}
509pub fn WEXITSTATUS(s: i32) i32 {
510 return signed((unsigned(s) & 0xff00) >> 8);
511}
512pub fn WTERMSIG(s: i32) i32 {
513 return signed(unsigned(s) & 0x7f);
514}
515pub fn WSTOPSIG(s: i32) i32 {
516 return WEXITSTATUS(s);
517}
518pub fn WIFEXITED(s: i32) bool {
519 return WTERMSIG(s) == 0;
520}
521pub fn WIFSTOPPED(s: i32) bool {
522 return @intCast(u16, (((unsigned(s) & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
523}
524pub fn WIFSIGNALED(s: i32) bool {
525 return (unsigned(s) & 0xffff) -% 1 < 0xff;
526}
527
528pub const winsize = extern struct {
529 ws_row: u16,
530 ws_col: u16,
531 ws_xpixel: u16,
532 ws_ypixel: u16,
533};
534
535/// Get the errno from a syscall return value, or 0 for no error.
536pub fn getErrno(r: usize) usize {
537 const signed_r = @bitCast(isize, r);
538 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
539}
540
541pub fn dup2(old: i32, new: i32) usize {
542 return arch.syscall2(SYS_dup2, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)));
543}
544
545pub fn chdir(path: [*]const u8) usize {
546 return arch.syscall1(SYS_chdir, @ptrToInt(path));
547}
548
549pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) usize {
550 return arch.syscall3(SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));
551}
552
553pub fn fork() usize {
554 return arch.syscall0(SYS_fork);
555}
556
557pub fn getcwd(buf: [*]u8, size: usize) usize {
558 return arch.syscall2(SYS___getcwd, @ptrToInt(buf), size);
559}
560
561pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
562 return arch.syscall3(SYS_getdents, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count);
563}
564
565pub fn isatty(fd: i32) bool {
566 var wsz: winsize = undefined;
567 return arch.syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
568}
569
570pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
571 return arch.syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
572}
573
574pub fn mkdir(path: [*]const u8, mode: u32) usize {
575 return arch.syscall2(SYS_mkdir, @ptrToInt(path), mode);
576}
577
578pub fn mmap(address: ?*u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) usize {
579 return arch.syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset));
580}
581
582pub fn munmap(address: usize, length: usize) usize {
583 return arch.syscall2(SYS_munmap, address, length);
584}
585
586pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
587 return arch.syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
588}
589
590pub fn rmdir(path: [*]const u8) usize {
591 return arch.syscall1(SYS_rmdir, @ptrToInt(path));
592}
593
594pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
595 return arch.syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
596}
597
598pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
599 return arch.syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
600}
601
602pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: usize) usize {
603 return arch.syscall4(SYS_preadv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset);
604}
605
606pub fn pipe(fd: *[2]i32) usize {
607 return pipe2(fd, 0);
608}
609
610pub fn pipe2(fd: *[2]i32, flags: usize) usize {
611 return arch.syscall2(SYS_pipe2, @ptrToInt(fd), flags);
612}
613
614pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
615 return arch.syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
616}
617
618pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
619 return arch.syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
620}
621
622pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) usize {
623 return arch.syscall4(SYS_pwritev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset);
624}
625
626pub fn rename(old: [*]const u8, new: [*]const u8) usize {
627 return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
628}
629
630pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
631 return arch.syscall3(SYS_open, @ptrToInt(path), flags, perm);
632}
633
634pub fn create(path: [*]const u8, perm: usize) usize {
635 return arch.syscall2(SYS_creat, @ptrToInt(path), perm);
636}
637
638pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize {
639 return arch.syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode);
640}
641
642pub fn close(fd: i32) usize {
643 return arch.syscall1(SYS_close, @bitCast(usize, isize(fd)));
644}
645
646pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {
647 return arch.syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), ref_pos);
648}
649
650pub fn exit(status: i32) noreturn {
651 _ = arch.syscall1(SYS_exit, @bitCast(usize, isize(status)));
652 unreachable;
653}
654
655pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
656 return arch.syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags));
657}
658
659pub fn kill(pid: i32, sig: i32) usize {
660 return arch.syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig)));
661}
662
663pub fn unlink(path: [*]const u8) usize {
664 return arch.syscall1(SYS_unlink, @ptrToInt(path));
665}
666
667pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
668 return arch.syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
669}
670
671pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
672 return arch.syscall2(SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem));
673}
674
675pub fn setuid(uid: u32) usize {
676 return arch.syscall1(SYS_setuid, uid);
677}
678
679pub fn setgid(gid: u32) usize {
680 return arch.syscall1(SYS_setgid, gid);
681}
682
683pub fn setreuid(ruid: u32, euid: u32) usize {
684 return arch.syscall2(SYS_setreuid, ruid, euid);
685}
686
687pub fn setregid(rgid: u32, egid: u32) usize {
688 return arch.syscall2(SYS_setregid, rgid, egid);
689}
690
691const NSIG = 32;
692
693pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
694pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
695pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
696
697/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
698pub const Sigaction = extern struct {
699 /// signal handler
700 __sigaction_u: extern union {
701 __sa_handler: extern fn (i32) void,
702 __sa_sigaction: extern fn (i32, *__siginfo, usize) void,
703 },
704
705 /// see signal options
706 sa_flags: u32,
707
708 /// signal mask to apply
709 sa_mask: sigset_t,
710};
711
712pub const _SIG_WORDS = 4;
713pub const _SIG_MAXSIG = 128;
714
715pub inline fn _SIG_IDX(sig: usize) usize {
716 return sig - 1;
717}
718pub inline fn _SIG_WORD(sig: usize) usize {
719 return_SIG_IDX(sig) >> 5;
720}
721pub inline fn _SIG_BIT(sig: usize) usize {
722 return 1 << (_SIG_IDX(sig) & 31);
723}
724pub inline fn _SIG_VALID(sig: usize) usize {
725 return sig <= _SIG_MAXSIG and sig > 0;
726}
727
728pub const sigset_t = extern struct {
729 __bits: [_SIG_WORDS]u32,
730};
731
732pub fn raise(sig: i32) usize {
733 // TODO have a chat with the freebsd folks and make sure there's no bug in
734 // their libc. musl-libc blocks signals in between these calls because
735 // if a signal handler runs and forks between the gettid and sending the
736 // signal, the parent will get 2 signals, one from itself and one from the child
737 // if the protection does not belong here, then it belongs in abort(),
738 // like it does in freebsd's libc.
739 var id: usize = undefined;
740 const rc = arch.syscall1(SYS_thr_self, @ptrToInt(&id));
741 if (getErrno(rc) != 0) return rc;
742 return arch.syscall2(SYS_thr_kill, id, @bitCast(usize, isize(sig)));
743}
744
745pub const Stat = arch.Stat;
746pub const timespec = arch.timespec;
747
748pub fn fstat(fd: i32, stat_buf: *Stat) usize {
749 return arch.syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));
750}
751
752pub const iovec = extern struct {
753 iov_base: [*]u8,
754 iov_len: usize,
755};
756
757pub const iovec_const = extern struct {
758 iov_base: [*]const u8,
759 iov_len: usize,
760};
761
762// TODO avoid libc dependency
763pub fn kqueue() usize {
764 return errnoWrap(c.kqueue());
765}
766
767// TODO avoid libc dependency
768pub fn kevent(kq: i32, changelist: []const Kevent, eventlist: []Kevent, timeout: ?*const timespec) usize {
769 return errnoWrap(c.kevent(
770 kq,
771 changelist.ptr,
772 @intCast(c_int, changelist.len),
773 eventlist.ptr,
774 @intCast(c_int, eventlist.len),
775 timeout,
776 ));
777}
778
779// TODO avoid libc dependency
780pub fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
781 return errnoWrap(c.sysctl(name, namelen, oldp, oldlenp, newp, newlen));
782}
783
784// TODO avoid libc dependency
785pub fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
786 return errnoWrap(c.sysctlbyname(name, oldp, oldlenp, newp, newlen));
787}
788
789// TODO avoid libc dependency
790pub fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) usize {
791 return errnoWrap(c.sysctlnametomib(name, wibp, sizep));
792}
793
794// TODO avoid libc dependency
795
796/// Takes the return value from a syscall and formats it back in the way
797/// that the kernel represents it to libc. Errno was a mistake, let's make
798/// it go away forever.
799fn errnoWrap(value: isize) usize {
800 return @bitCast(usize, if (value == -1) -isize(c._errno().*) else value);
801}
std/os/freebsd/syscall.zig created+493
......@@ -0,0 +1,493 @@
1pub const SYS_syscall = 0;
2pub const SYS_exit = 1;
3pub const SYS_fork = 2;
4pub const SYS_read = 3;
5pub const SYS_write = 4;
6pub const SYS_open = 5;
7pub const SYS_close = 6;
8pub const SYS_wait4 = 7;
9// 8 is old creat
10pub const SYS_link = 9;
11pub const SYS_unlink = 10;
12// 11 is obsolete execv
13pub const SYS_chdir = 12;
14pub const SYS_fchdir = 13;
15pub const SYS_freebsd11_mknod = 14;
16pub const SYS_chmod = 15;
17pub const SYS_chown = 16;
18pub const SYS_break = 17;
19// 18 is freebsd4 getfsstat
20// 19 is old lseek
21pub const SYS_getpid = 20;
22pub const SYS_mount = 21;
23pub const SYS_unmount = 22;
24pub const SYS_setuid = 23;
25pub const SYS_getuid = 24;
26pub const SYS_geteuid = 25;
27pub const SYS_ptrace = 26;
28pub const SYS_recvmsg = 27;
29pub const SYS_sendmsg = 28;
30pub const SYS_recvfrom = 29;
31pub const SYS_accept = 30;
32pub const SYS_getpeername = 31;
33pub const SYS_getsockname = 32;
34pub const SYS_access = 33;
35pub const SYS_chflags = 34;
36pub const SYS_fchflags = 35;
37pub const SYS_sync = 36;
38pub const SYS_kill = 37;
39// 38 is old stat
40pub const SYS_getppid = 39;
41// 40 is old lstat
42pub const SYS_dup = 41;
43pub const SYS_freebsd10_pipe = 42;
44pub const SYS_getegid = 43;
45pub const SYS_profil = 44;
46pub const SYS_ktrace = 45;
47// 46 is old sigaction
48pub const SYS_getgid = 47;
49// 48 is old sigprocmask
50pub const SYS_getlogin = 49;
51pub const SYS_setlogin = 50;
52pub const SYS_acct = 51;
53// 52 is old sigpending
54pub const SYS_sigaltstack = 53;
55pub const SYS_ioctl = 54;
56pub const SYS_reboot = 55;
57pub const SYS_revoke = 56;
58pub const SYS_symlink = 57;
59pub const SYS_readlink = 58;
60pub const SYS_execve = 59;
61pub const SYS_umask = 60;
62pub const SYS_chroot = 61;
63// 62 is old fstat
64// 63 is old getkerninfo
65// 64 is old getpagesize
66pub const SYS_msync = 65;
67pub const SYS_vfork = 66;
68// 67 is obsolete vread
69// 68 is obsolete vwrite
70// 69 is obsolete sbrk (still present on some platforms)
71pub const SYS_sstk = 70;
72// 71 is old mmap
73pub const SYS_vadvise = 72;
74pub const SYS_munmap = 73;
75pub const SYS_mprotect = 74;
76pub const SYS_madvise = 75;
77// 76 is obsolete vhangup
78// 77 is obsolete vlimit
79pub const SYS_mincore = 78;
80pub const SYS_getgroups = 79;
81pub const SYS_setgroups = 80;
82pub const SYS_getpgrp = 81;
83pub const SYS_setpgid = 82;
84pub const SYS_setitimer = 83;
85// 84 is old wait
86pub const SYS_swapon = 85;
87pub const SYS_getitimer = 86;
88// 87 is old gethostname
89// 88 is old sethostname
90pub const SYS_getdtablesize = 89;
91pub const SYS_dup2 = 90;
92pub const SYS_fcntl = 92;
93pub const SYS_select = 93;
94pub const SYS_fsync = 95;
95pub const SYS_setpriority = 96;
96pub const SYS_socket = 97;
97pub const SYS_connect = 98;
98// 99 is old accept
99pub const SYS_getpriority = 100;
100// 101 is old send
101// 102 is old recv
102// 103 is old sigreturn
103pub const SYS_bind = 104;
104pub const SYS_setsockopt = 105;
105pub const SYS_listen = 106;
106// 107 is obsolete vtimes
107// 108 is old sigvec
108// 109 is old sigblock
109// 110 is old sigsetmask
110// 111 is old sigsuspend
111// 112 is old sigstack
112// 113 is old recvmsg
113// 114 is old sendmsg
114// 115 is obsolete vtrace
115pub const SYS_gettimeofday = 116;
116pub const SYS_getrusage = 117;
117pub const SYS_getsockopt = 118;
118pub const SYS_readv = 120;
119pub const SYS_writev = 121;
120pub const SYS_settimeofday = 122;
121pub const SYS_fchown = 123;
122pub const SYS_fchmod = 124;
123// 125 is old recvfrom
124pub const SYS_setreuid = 126;
125pub const SYS_setregid = 127;
126pub const SYS_rename = 128;
127// 129 is old truncate
128// 130 is old ftruncate
129pub const SYS_flock = 131;
130pub const SYS_mkfifo = 132;
131pub const SYS_sendto = 133;
132pub const SYS_shutdown = 134;
133pub const SYS_socketpair = 135;
134pub const SYS_mkdir = 136;
135pub const SYS_rmdir = 137;
136pub const SYS_utimes = 138;
137// 139 is obsolete 4.2 sigreturn
138pub const SYS_adjtime = 140;
139// 141 is old getpeername
140// 142 is old gethostid
141// 143 is old sethostid
142// 144 is old getrlimit
143// 145 is old setrlimit
144// 146 is old killpg
145pub const SYS_setsid = 147;
146pub const SYS_quotactl = 148;
147// 149 is old quota
148// 150 is old getsockname
149pub const SYS_nlm_syscall = 154;
150pub const SYS_nfssvc = 155;
151// 156 is old getdirentries
152// 157 is freebsd4 statfs
153// 158 is freebsd4 fstatfs
154pub const SYS_lgetfh = 160;
155pub const SYS_getfh = 161;
156// 162 is freebsd4 getdomainname
157// 163 is freebsd4 setdomainname
158// 164 is freebsd4 uname
159pub const SYS_sysarch = 165;
160pub const SYS_rtprio = 166;
161pub const SYS_semsys = 169;
162pub const SYS_msgsys = 170;
163pub const SYS_shmsys = 171;
164// 173 is freebsd6 pread
165// 174 is freebsd6 pwrite
166pub const SYS_setfib = 175;
167pub const SYS_ntp_adjtime = 176;
168pub const SYS_setgid = 181;
169pub const SYS_setegid = 182;
170pub const SYS_seteuid = 183;
171// 184 is obsolete lfs_bmapv
172// 185 is obsolete lfs_markv
173// 186 is obsolete lfs_segclean
174// 187 is obsolete lfs_segwait
175pub const SYS_freebsd11_stat = 188;
176pub const SYS_freebsd11_fstat = 189;
177pub const SYS_freebsd11_lstat = 190;
178pub const SYS_pathconf = 191;
179pub const SYS_fpathconf = 192;
180pub const SYS_getrlimit = 194;
181pub const SYS_setrlimit = 195;
182pub const SYS_freebsd11_getdirentries = 196;
183// 197 is freebsd6 mmap
184pub const SYS___syscall = 198;
185// 199 is freebsd6 lseek
186// 200 is freebsd6 truncate
187// 201 is freebsd6 ftruncate
188pub const SYS___sysctl = 202;
189pub const SYS_mlock = 203;
190pub const SYS_munlock = 204;
191pub const SYS_undelete = 205;
192pub const SYS_futimes = 206;
193pub const SYS_getpgid = 207;
194pub const SYS_poll = 209;
195pub const SYS_freebsd7___semctl = 220;
196pub const SYS_semget = 221;
197pub const SYS_semop = 222;
198pub const SYS_freebsd7_msgctl = 224;
199pub const SYS_msgget = 225;
200pub const SYS_msgsnd = 226;
201pub const SYS_msgrcv = 227;
202pub const SYS_shmat = 228;
203pub const SYS_freebsd7_shmctl = 229;
204pub const SYS_shmdt = 230;
205pub const SYS_shmget = 231;
206pub const SYS_clock_gettime = 232;
207pub const SYS_clock_settime = 233;
208pub const SYS_clock_getres = 234;
209pub const SYS_ktimer_create = 235;
210pub const SYS_ktimer_delete = 236;
211pub const SYS_ktimer_settime = 237;
212pub const SYS_ktimer_gettime = 238;
213pub const SYS_ktimer_getoverrun = 239;
214pub const SYS_nanosleep = 240;
215pub const SYS_ffclock_getcounter = 241;
216pub const SYS_ffclock_setestimate = 242;
217pub const SYS_ffclock_getestimate = 243;
218pub const SYS_clock_nanosleep = 244;
219pub const SYS_clock_getcpuclockid2 = 247;
220pub const SYS_ntp_gettime = 248;
221pub const SYS_minherit = 250;
222pub const SYS_rfork = 251;
223// 252 is obsolete openbsd_poll
224pub const SYS_issetugid = 253;
225pub const SYS_lchown = 254;
226pub const SYS_aio_read = 255;
227pub const SYS_aio_write = 256;
228pub const SYS_lio_listio = 257;
229pub const SYS_freebsd11_getdents = 272;
230pub const SYS_lchmod = 274;
231// 275 is obsolete netbsd_lchown
232pub const SYS_lutimes = 276;
233// 277 is obsolete netbsd_msync
234pub const SYS_freebsd11_nstat = 278;
235pub const SYS_freebsd11_nfstat = 279;
236pub const SYS_freebsd11_nlstat = 280;
237pub const SYS_preadv = 289;
238pub const SYS_pwritev = 290;
239// 297 is freebsd4 fhstatfs
240pub const SYS_fhopen = 298;
241pub const SYS_freebsd11_fhstat = 299;
242pub const SYS_modnext = 300;
243pub const SYS_modstat = 301;
244pub const SYS_modfnext = 302;
245pub const SYS_modfind = 303;
246pub const SYS_kldload = 304;
247pub const SYS_kldunload = 305;
248pub const SYS_kldfind = 306;
249pub const SYS_kldnext = 307;
250pub const SYS_kldstat = 308;
251pub const SYS_kldfirstmod = 309;
252pub const SYS_getsid = 310;
253pub const SYS_setresuid = 311;
254pub const SYS_setresgid = 312;
255// 313 is obsolete signanosleep
256pub const SYS_aio_return = 314;
257pub const SYS_aio_suspend = 315;
258pub const SYS_aio_cancel = 316;
259pub const SYS_aio_error = 317;
260// 318 is freebsd6 aio_read
261// 319 is freebsd6 aio_write
262// 320 is freebsd6 lio_listio
263pub const SYS_yield = 321;
264// 322 is obsolete thr_sleep
265// 323 is obsolete thr_wakeup
266pub const SYS_mlockall = 324;
267pub const SYS_munlockall = 325;
268pub const SYS___getcwd = 326;
269pub const SYS_sched_setparam = 327;
270pub const SYS_sched_getparam = 328;
271pub const SYS_sched_setscheduler = 329;
272pub const SYS_sched_getscheduler = 330;
273pub const SYS_sched_yield = 331;
274pub const SYS_sched_get_priority_max = 332;
275pub const SYS_sched_get_priority_min = 333;
276pub const SYS_sched_rr_get_interval = 334;
277pub const SYS_utrace = 335;
278// 336 is freebsd4 sendfile
279pub const SYS_kldsym = 337;
280pub const SYS_jail = 338;
281pub const SYS_nnpfs_syscall = 339;
282pub const SYS_sigprocmask = 340;
283pub const SYS_sigsuspend = 341;
284// 342 is freebsd4 sigaction
285pub const SYS_sigpending = 343;
286// 344 is freebsd4 sigreturn
287pub const SYS_sigtimedwait = 345;
288pub const SYS_sigwaitinfo = 346;
289pub const SYS___acl_get_file = 347;
290pub const SYS___acl_set_file = 348;
291pub const SYS___acl_get_fd = 349;
292pub const SYS___acl_set_fd = 350;
293pub const SYS___acl_delete_file = 351;
294pub const SYS___acl_delete_fd = 352;
295pub const SYS___acl_aclcheck_file = 353;
296pub const SYS___acl_aclcheck_fd = 354;
297pub const SYS_extattrctl = 355;
298pub const SYS_extattr_set_file = 356;
299pub const SYS_extattr_get_file = 357;
300pub const SYS_extattr_delete_file = 358;
301pub const SYS_aio_waitcomplete = 359;
302pub const SYS_getresuid = 360;
303pub const SYS_getresgid = 361;
304pub const SYS_kqueue = 362;
305pub const SYS_freebsd11_kevent = 363;
306// 364 is obsolete __cap_get_proc
307// 365 is obsolete __cap_set_proc
308// 366 is obsolete __cap_get_fd
309// 367 is obsolete __cap_get_file
310// 368 is obsolete __cap_set_fd
311// 369 is obsolete __cap_set_file
312pub const SYS_extattr_set_fd = 371;
313pub const SYS_extattr_get_fd = 372;
314pub const SYS_extattr_delete_fd = 373;
315pub const SYS___setugid = 374;
316pub const SYS_eaccess = 376;
317pub const SYS_afs3_syscall = 377;
318pub const SYS_nmount = 378;
319// 379 is obsolete kse_exit
320// 380 is obsolete kse_wakeup
321// 381 is obsolete kse_create
322// 382 is obsolete kse_thr_interrupt
323// 383 is obsolete kse_release
324pub const SYS___mac_get_proc = 384;
325pub const SYS___mac_set_proc = 385;
326pub const SYS___mac_get_fd = 386;
327pub const SYS___mac_get_file = 387;
328pub const SYS___mac_set_fd = 388;
329pub const SYS___mac_set_file = 389;
330pub const SYS_kenv = 390;
331pub const SYS_lchflags = 391;
332pub const SYS_uuidgen = 392;
333pub const SYS_sendfile = 393;
334pub const SYS_mac_syscall = 394;
335pub const SYS_freebsd11_getfsstat = 395;
336pub const SYS_freebsd11_statfs = 396;
337pub const SYS_freebsd11_fstatfs = 397;
338pub const SYS_freebsd11_fhstatfs = 398;
339pub const SYS_ksem_close = 400;
340pub const SYS_ksem_post = 401;
341pub const SYS_ksem_wait = 402;
342pub const SYS_ksem_trywait = 403;
343pub const SYS_ksem_init = 404;
344pub const SYS_ksem_open = 405;
345pub const SYS_ksem_unlink = 406;
346pub const SYS_ksem_getvalue = 407;
347pub const SYS_ksem_destroy = 408;
348pub const SYS___mac_get_pid = 409;
349pub const SYS___mac_get_link = 410;
350pub const SYS___mac_set_link = 411;
351pub const SYS_extattr_set_link = 412;
352pub const SYS_extattr_get_link = 413;
353pub const SYS_extattr_delete_link = 414;
354pub const SYS___mac_execve = 415;
355pub const SYS_sigaction = 416;
356pub const SYS_sigreturn = 417;
357pub const SYS_getcontext = 421;
358pub const SYS_setcontext = 422;
359pub const SYS_swapcontext = 423;
360pub const SYS_swapoff = 424;
361pub const SYS___acl_get_link = 425;
362pub const SYS___acl_set_link = 426;
363pub const SYS___acl_delete_link = 427;
364pub const SYS___acl_aclcheck_link = 428;
365pub const SYS_sigwait = 429;
366pub const SYS_thr_create = 430;
367pub const SYS_thr_exit = 431;
368pub const SYS_thr_self = 432;
369pub const SYS_thr_kill = 433;
370pub const SYS_jail_attach = 436;
371pub const SYS_extattr_list_fd = 437;
372pub const SYS_extattr_list_file = 438;
373pub const SYS_extattr_list_link = 439;
374// 440 is obsolete kse_switchin
375pub const SYS_ksem_timedwait = 441;
376pub const SYS_thr_suspend = 442;
377pub const SYS_thr_wake = 443;
378pub const SYS_kldunloadf = 444;
379pub const SYS_audit = 445;
380pub const SYS_auditon = 446;
381pub const SYS_getauid = 447;
382pub const SYS_setauid = 448;
383pub const SYS_getaudit = 449;
384pub const SYS_setaudit = 450;
385pub const SYS_getaudit_addr = 451;
386pub const SYS_setaudit_addr = 452;
387pub const SYS_auditctl = 453;
388pub const SYS__umtx_op = 454;
389pub const SYS_thr_new = 455;
390pub const SYS_sigqueue = 456;
391pub const SYS_kmq_open = 457;
392pub const SYS_kmq_setattr = 458;
393pub const SYS_kmq_timedreceive = 459;
394pub const SYS_kmq_timedsend = 460;
395pub const SYS_kmq_notify = 461;
396pub const SYS_kmq_unlink = 462;
397pub const SYS_abort2 = 463;
398pub const SYS_thr_set_name = 464;
399pub const SYS_aio_fsync = 465;
400pub const SYS_rtprio_thread = 466;
401pub const SYS_sctp_peeloff = 471;
402pub const SYS_sctp_generic_sendmsg = 472;
403pub const SYS_sctp_generic_sendmsg_iov = 473;
404pub const SYS_sctp_generic_recvmsg = 474;
405pub const SYS_pread = 475;
406pub const SYS_pwrite = 476;
407pub const SYS_mmap = 477;
408pub const SYS_lseek = 478;
409pub const SYS_truncate = 479;
410pub const SYS_ftruncate = 480;
411pub const SYS_thr_kill2 = 481;
412pub const SYS_shm_open = 482;
413pub const SYS_shm_unlink = 483;
414pub const SYS_cpuset = 484;
415pub const SYS_cpuset_setid = 485;
416pub const SYS_cpuset_getid = 486;
417pub const SYS_cpuset_getaffinity = 487;
418pub const SYS_cpuset_setaffinity = 488;
419pub const SYS_faccessat = 489;
420pub const SYS_fchmodat = 490;
421pub const SYS_fchownat = 491;
422pub const SYS_fexecve = 492;
423pub const SYS_freebsd11_fstatat = 493;
424pub const SYS_futimesat = 494;
425pub const SYS_linkat = 495;
426pub const SYS_mkdirat = 496;
427pub const SYS_mkfifoat = 497;
428pub const SYS_freebsd11_mknodat = 498;
429pub const SYS_openat = 499;
430pub const SYS_readlinkat = 500;
431pub const SYS_renameat = 501;
432pub const SYS_symlinkat = 502;
433pub const SYS_unlinkat = 503;
434pub const SYS_posix_openpt = 504;
435pub const SYS_gssd_syscall = 505;
436pub const SYS_jail_get = 506;
437pub const SYS_jail_set = 507;
438pub const SYS_jail_remove = 508;
439pub const SYS_closefrom = 509;
440pub const SYS___semctl = 510;
441pub const SYS_msgctl = 511;
442pub const SYS_shmctl = 512;
443pub const SYS_lpathconf = 513;
444// 514 is obsolete cap_new
445pub const SYS___cap_rights_get = 515;
446pub const SYS_cap_enter = 516;
447pub const SYS_cap_getmode = 517;
448pub const SYS_pdfork = 518;
449pub const SYS_pdkill = 519;
450pub const SYS_pdgetpid = 520;
451pub const SYS_pselect = 522;
452pub const SYS_getloginclass = 523;
453pub const SYS_setloginclass = 524;
454pub const SYS_rctl_get_racct = 525;
455pub const SYS_rctl_get_rules = 526;
456pub const SYS_rctl_get_limits = 527;
457pub const SYS_rctl_add_rule = 528;
458pub const SYS_rctl_remove_rule = 529;
459pub const SYS_posix_fallocate = 530;
460pub const SYS_posix_fadvise = 531;
461pub const SYS_wait6 = 532;
462pub const SYS_cap_rights_limit = 533;
463pub const SYS_cap_ioctls_limit = 534;
464pub const SYS_cap_ioctls_get = 535;
465pub const SYS_cap_fcntls_limit = 536;
466pub const SYS_cap_fcntls_get = 537;
467pub const SYS_bindat = 538;
468pub const SYS_connectat = 539;
469pub const SYS_chflagsat = 540;
470pub const SYS_accept4 = 541;
471pub const SYS_pipe2 = 542;
472pub const SYS_aio_mlock = 543;
473pub const SYS_procctl = 544;
474pub const SYS_ppoll = 545;
475pub const SYS_futimens = 546;
476pub const SYS_utimensat = 547;
477// 548 is obsolete numa_getaffinity
478// 549 is obsolete numa_setaffinity
479pub const SYS_fdatasync = 550;
480pub const SYS_fstat = 551;
481pub const SYS_fstatat = 552;
482pub const SYS_fhstat = 553;
483pub const SYS_getdirentries = 554;
484pub const SYS_statfs = 555;
485pub const SYS_fstatfs = 556;
486pub const SYS_getfsstat = 557;
487pub const SYS_fhstatfs = 558;
488pub const SYS_mknodat = 559;
489pub const SYS_kevent = 560;
490pub const SYS_cpuset_getdomain = 561;
491pub const SYS_cpuset_setdomain = 562;
492pub const SYS_getrandom = 563;
493pub const SYS_MAXSYSCALL = 564;
std/os/freebsd/x86_64.zig created+136
......@@ -0,0 +1,136 @@
1const freebsd = @import("index.zig");
2const socklen_t = freebsd.socklen_t;
3const iovec = freebsd.iovec;
4
5pub const SYS_sbrk = 69;
6
7pub fn syscall0(number: usize) usize {
8 return asm volatile ("syscall"
9 : [ret] "={rax}" (-> usize)
10 : [number] "{rax}" (number)
11 : "rcx", "r11"
12 );
13}
14
15pub fn syscall1(number: usize, arg1: usize) usize {
16 return asm volatile ("syscall"
17 : [ret] "={rax}" (-> usize)
18 : [number] "{rax}" (number),
19 [arg1] "{rdi}" (arg1)
20 : "rcx", "r11"
21 );
22}
23
24pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
25 return asm volatile ("syscall"
26 : [ret] "={rax}" (-> usize)
27 : [number] "{rax}" (number),
28 [arg1] "{rdi}" (arg1),
29 [arg2] "{rsi}" (arg2)
30 : "rcx", "r11"
31 );
32}
33
34pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
35 return asm volatile ("syscall"
36 : [ret] "={rax}" (-> usize)
37 : [number] "{rax}" (number),
38 [arg1] "{rdi}" (arg1),
39 [arg2] "{rsi}" (arg2),
40 [arg3] "{rdx}" (arg3)
41 : "rcx", "r11"
42 );
43}
44
45pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
46 return asm volatile ("syscall"
47 : [ret] "={rax}" (-> usize)
48 : [number] "{rax}" (number),
49 [arg1] "{rdi}" (arg1),
50 [arg2] "{rsi}" (arg2),
51 [arg3] "{rdx}" (arg3),
52 [arg4] "{r10}" (arg4)
53 : "rcx", "r11"
54 );
55}
56
57pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
58 return asm volatile ("syscall"
59 : [ret] "={rax}" (-> usize)
60 : [number] "{rax}" (number),
61 [arg1] "{rdi}" (arg1),
62 [arg2] "{rsi}" (arg2),
63 [arg3] "{rdx}" (arg3),
64 [arg4] "{r10}" (arg4),
65 [arg5] "{r8}" (arg5)
66 : "rcx", "r11"
67 );
68}
69
70pub fn syscall6(
71 number: usize,
72 arg1: usize,
73 arg2: usize,
74 arg3: usize,
75 arg4: usize,
76 arg5: usize,
77 arg6: usize,
78) usize {
79 return asm volatile ("syscall"
80 : [ret] "={rax}" (-> usize)
81 : [number] "{rax}" (number),
82 [arg1] "{rdi}" (arg1),
83 [arg2] "{rsi}" (arg2),
84 [arg3] "{rdx}" (arg3),
85 [arg4] "{r10}" (arg4),
86 [arg5] "{r8}" (arg5),
87 [arg6] "{r9}" (arg6)
88 : "rcx", "r11"
89 );
90}
91
92pub nakedcc fn restore_rt() void {
93 asm volatile ("syscall"
94 :
95 : [number] "{rax}" (usize(SYS_rt_sigreturn))
96 : "rcx", "r11"
97 );
98}
99
100pub const msghdr = extern struct {
101 msg_name: *u8,
102 msg_namelen: socklen_t,
103 msg_iov: *iovec,
104 msg_iovlen: i32,
105 __pad1: i32,
106 msg_control: *u8,
107 msg_controllen: socklen_t,
108 __pad2: socklen_t,
109 msg_flags: i32,
110};
111
112/// Renamed to Stat to not conflict with the stat function.
113pub const Stat = extern struct {
114 dev: u64,
115 ino: u64,
116 nlink: usize,
117
118 mode: u32,
119 uid: u32,
120 gid: u32,
121 __pad0: u32,
122 rdev: u64,
123 size: i64,
124 blksize: isize,
125 blocks: i64,
126
127 atim: timespec,
128 mtim: timespec,
129 ctim: timespec,
130 __unused: [3]isize,
131};
132
133pub const timespec = extern struct {
134 tv_sec: isize,
135 tv_nsec: isize,
136};
std/os/get_app_data_dir.zig+1-1
......@@ -43,7 +43,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
4343 };
4444 return os.path.join(allocator, home_dir, "Library", "Application Support", appname);
4545 },
46 builtin.Os.linux => {
46 builtin.Os.linux, builtin.Os.freebsd => {
4747 const home_dir = os.getEnvPosix("HOME") orelse {
4848 // TODO look in /etc/passwd
4949 return error.AppDataDirUnavailable;
std/os/get_user_id.zig+1-1
......@@ -11,7 +11,7 @@ pub const UserInfo = struct {
1111/// POSIX function which gets a uid from username.
1212pub fn getUserInfo(name: []const u8) !UserInfo {
1313 return switch (builtin.os) {
14 Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),
14 Os.linux, Os.macosx, Os.ios, Os.freebsd => posixGetUserInfo(name),
1515 else => @compileError("Unsupported OS"),
1616 };
1717}
std/os/index.zig+67-28
......@@ -3,7 +3,7 @@ const builtin = @import("builtin");
33const Os = builtin.Os;
44const is_windows = builtin.os == Os.windows;
55const is_posix = switch (builtin.os) {
6 builtin.Os.linux, builtin.Os.macosx => true,
6 builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => true,
77 else => false,
88};
99const os = @This();
......@@ -24,10 +24,12 @@ test "std.os" {
2424pub const windows = @import("windows/index.zig");
2525pub const darwin = @import("darwin.zig");
2626pub const linux = @import("linux/index.zig");
27pub const freebsd = @import("freebsd/index.zig");
2728pub const zen = @import("zen.zig");
2829pub const posix = switch (builtin.os) {
2930 Os.linux => linux,
3031 Os.macosx, Os.ios => darwin,
32 Os.freebsd => freebsd,
3133 Os.zen => zen,
3234 else => @compileError("Unsupported OS"),
3335};
......@@ -40,7 +42,7 @@ pub const time = @import("time.zig");
4042
4143pub const page_size = 4 * 1024;
4244pub const MAX_PATH_BYTES = switch (builtin.os) {
43 Os.linux, Os.macosx, Os.ios => posix.PATH_MAX,
45 Os.linux, Os.macosx, Os.ios, Os.freebsd => posix.PATH_MAX,
4446 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
4547 // If it would require 4 UTF-8 bytes, then there would be a surrogate
4648 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
......@@ -101,7 +103,7 @@ const math = std.math;
101103/// library implementation.
102104pub fn getRandomBytes(buf: []u8) !void {
103105 switch (builtin.os) {
104 Os.linux => while (true) {
106 Os.linux, Os.freebsd => while (true) {
105107 // TODO check libc version and potentially call c.getrandom.
106108 // See #397
107109 const errno = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0));
......@@ -174,7 +176,7 @@ pub fn abort() noreturn {
174176 c.abort();
175177 }
176178 switch (builtin.os) {
177 Os.linux, Os.macosx, Os.ios => {
179 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
178180 _ = posix.raise(posix.SIGABRT);
179181 _ = posix.raise(posix.SIGKILL);
180182 while (true) {}
......@@ -196,7 +198,7 @@ pub fn exit(status: u8) noreturn {
196198 c.exit(status);
197199 }
198200 switch (builtin.os) {
199 Os.linux, Os.macosx, Os.ios => {
201 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
200202 posix.exit(status);
201203 },
202204 Os.windows => {
......@@ -419,7 +421,7 @@ pub fn posix_pwritev(fd: i32, iov: [*]const posix.iovec_const, count: usize, off
419421 }
420422 }
421423 },
422 builtin.Os.linux => while (true) {
424 builtin.Os.linux, builtin.Os.freebsd => while (true) {
423425 const rc = posix.pwritev(fd, iov, count, offset);
424426 const err = posix.getErrno(rc);
425427 switch (err) {
......@@ -457,6 +459,7 @@ pub const PosixOpenError = error{
457459 NoSpaceLeft,
458460 NotDir,
459461 PathAlreadyExists,
462 DeviceBusy,
460463
461464 /// See https://github.com/ziglang/zig/issues/1396
462465 Unexpected,
......@@ -495,6 +498,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 {
495498 posix.ENOTDIR => return PosixOpenError.NotDir,
496499 posix.EPERM => return PosixOpenError.AccessDenied,
497500 posix.EEXIST => return PosixOpenError.PathAlreadyExists,
501 posix.EBUSY => return PosixOpenError.DeviceBusy,
498502 else => return unexpectedErrorPosix(err),
499503 }
500504 }
......@@ -687,7 +691,7 @@ pub fn getBaseAddress() usize {
687691 };
688692 return phdr - @sizeOf(ElfHeader);
689693 },
690 builtin.Os.macosx => return @ptrToInt(&std.c._mh_execute_header),
694 builtin.Os.macosx, builtin.Os.freebsd => return @ptrToInt(&std.c._mh_execute_header),
691695 builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
692696 else => @compileError("Unsupported OS"),
693697 }
......@@ -700,8 +704,8 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
700704 errdefer result.deinit();
701705
702706 if (is_windows) {
703 const ptr = windows.GetEnvironmentStringsA() orelse return error.OutOfMemory;
704 defer assert(windows.FreeEnvironmentStringsA(ptr) != 0);
707 const ptr = windows.GetEnvironmentStringsW() orelse return error.OutOfMemory;
708 defer assert(windows.FreeEnvironmentStringsW(ptr) != 0);
705709
706710 var i: usize = 0;
707711 while (true) {
......@@ -710,17 +714,21 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
710714 const key_start = i;
711715
712716 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
713 const key = ptr[key_start..i];
717 const key_w = ptr[key_start..i];
718 const key = try std.unicode.utf16leToUtf8Alloc(allocator, key_w);
719 errdefer allocator.free(key);
714720
715721 if (ptr[i] == '=') i += 1;
716722
717723 const value_start = i;
718724 while (ptr[i] != 0) : (i += 1) {}
719 const value = ptr[value_start..i];
725 const value_w = ptr[value_start..i];
726 const value = try std.unicode.utf16leToUtf8Alloc(allocator, value_w);
727 errdefer allocator.free(value);
720728
721729 i += 1; // skip over null byte
722730
723 try result.set(key, value);
731 try result.setMove(key, value);
724732 }
725733 } else {
726734 for (posix_environ_raw) |ptr| {
......@@ -738,6 +746,11 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
738746 }
739747}
740748
749test "os.getEnvMap" {
750 var env = try getEnvMap(std.debug.global_allocator);
751 defer env.deinit();
752}
753
741754/// TODO make this go through libc when we have it
742755pub fn getEnvPosix(key: []const u8) ?[]const u8 {
743756 for (posix_environ_raw) |ptr| {
......@@ -758,21 +771,24 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
758771pub const GetEnvVarOwnedError = error{
759772 OutOfMemory,
760773 EnvironmentVariableNotFound,
774
775 /// See https://github.com/ziglang/zig/issues/1774
776 InvalidUtf8,
761777};
762778
763779/// Caller must free returned memory.
764780/// TODO make this go through libc when we have it
765781pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
766782 if (is_windows) {
767 const key_with_null = try cstr.addNullByte(allocator, key);
783 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
768784 defer allocator.free(key_with_null);
769785
770 var buf = try allocator.alloc(u8, 256);
771 errdefer allocator.free(buf);
786 var buf = try allocator.alloc(u16, 256);
787 defer allocator.free(buf);
772788
773789 while (true) {
774790 const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;
775 const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
791 const result = windows.GetEnvironmentVariableW(key_with_null.ptr, buf.ptr, windows_buf_len);
776792
777793 if (result == 0) {
778794 const err = windows.GetLastError();
......@@ -786,11 +802,16 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
786802 }
787803
788804 if (result > buf.len) {
789 buf = try allocator.realloc(u8, buf, result);
805 buf = try allocator.realloc(u16, buf, result);
790806 continue;
791807 }
792808
793 return allocator.shrink(u8, buf, result);
809 return std.unicode.utf16leToUtf8Alloc(allocator, buf) catch |err| switch (err) {
810 error.DanglingSurrogateHalf => return error.InvalidUtf8,
811 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
812 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
813 error.OutOfMemory => return error.OutOfMemory,
814 };
794815 }
795816 } else {
796817 const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;
......@@ -798,6 +819,11 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
798819 }
799820}
800821
822test "os.getEnvVarOwned" {
823 var ga = debug.global_allocator;
824 debug.assertError(getEnvVarOwned(ga, "BADENV"), error.EnvironmentVariableNotFound);
825}
826
801827/// Caller must free the returned memory.
802828pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
803829 var buf: [MAX_PATH_BYTES]u8 = undefined;
......@@ -1305,7 +1331,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void {
13051331 const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path);
13061332 return deleteDirW(&dir_path_w);
13071333 },
1308 Os.linux, Os.macosx, Os.ios => {
1334 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
13091335 const err = posix.getErrno(posix.rmdir(dir_path));
13101336 switch (err) {
13111337 0 => return,
......@@ -1348,7 +1374,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void {
13481374 const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path);
13491375 return deleteDirW(&dir_path_w);
13501376 },
1351 Os.linux, Os.macosx, Os.ios => {
1377 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
13521378 const dir_path_c = try toPosixPath(dir_path);
13531379 return deleteDirC(&dir_path_c);
13541380 },
......@@ -1378,6 +1404,7 @@ const DeleteTreeError = error{
13781404 FileSystem,
13791405 FileBusy,
13801406 DirNotEmpty,
1407 DeviceBusy,
13811408
13821409 /// On Windows, file paths must be valid Unicode.
13831410 InvalidUtf8,
......@@ -1439,6 +1466,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!
14391466 error.Unexpected,
14401467 error.InvalidUtf8,
14411468 error.BadPathName,
1469 error.DeviceBusy,
14421470 => return err,
14431471 };
14441472 defer dir.close();
......@@ -1465,7 +1493,7 @@ pub const Dir = struct {
14651493 allocator: *Allocator,
14661494
14671495 pub const Handle = switch (builtin.os) {
1468 Os.macosx, Os.ios => struct {
1496 Os.macosx, Os.ios, Os.freebsd => struct {
14691497 fd: i32,
14701498 seek: i64,
14711499 buf: []u8,
......@@ -1521,6 +1549,7 @@ pub const Dir = struct {
15211549 OutOfMemory,
15221550 InvalidUtf8,
15231551 BadPathName,
1552 DeviceBusy,
15241553
15251554 /// See https://github.com/ziglang/zig/issues/1396
15261555 Unexpected,
......@@ -1541,7 +1570,7 @@ pub const Dir = struct {
15411570 .name_data = undefined,
15421571 };
15431572 },
1544 Os.macosx, Os.ios => Handle{
1573 Os.macosx, Os.ios, Os.freebsd => Handle{
15451574 .fd = try posixOpen(
15461575 dir_path,
15471576 posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC,
......@@ -1572,7 +1601,7 @@ pub const Dir = struct {
15721601 Os.windows => {
15731602 _ = windows.FindClose(self.handle.handle);
15741603 },
1575 Os.macosx, Os.ios, Os.linux => {
1604 Os.macosx, Os.ios, Os.linux, Os.freebsd => {
15761605 self.allocator.free(self.handle.buf);
15771606 os.close(self.handle.fd);
15781607 },
......@@ -1587,6 +1616,7 @@ pub const Dir = struct {
15871616 Os.linux => return self.nextLinux(),
15881617 Os.macosx, Os.ios => return self.nextDarwin(),
15891618 Os.windows => return self.nextWindows(),
1619 Os.freebsd => return self.nextFreebsd(),
15901620 else => @compileError("unimplemented"),
15911621 }
15921622 }
......@@ -1726,6 +1756,11 @@ pub const Dir = struct {
17261756 };
17271757 }
17281758 }
1759
1760 fn nextFreebsd(self: *Dir) !?Entry {
1761 //self.handle.buf = try self.allocator.alloc(u8, page_size);
1762 @compileError("TODO implement dirs for FreeBSD");
1763 }
17291764};
17301765
17311766pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void {
......@@ -2164,7 +2199,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {
21642199pub fn openSelfExe() !os.File {
21652200 switch (builtin.os) {
21662201 Os.linux => return os.File.openReadC(c"/proc/self/exe"),
2167 Os.macosx, Os.ios => {
2202 Os.macosx, Os.ios, Os.freebsd => {
21682203 var buf: [MAX_PATH_BYTES]u8 = undefined;
21692204 const self_exe_path = try selfExePath(&buf);
21702205 buf[self_exe_path.len] = 0;
......@@ -2181,7 +2216,7 @@ pub fn openSelfExe() !os.File {
21812216
21822217test "openSelfExe" {
21832218 switch (builtin.os) {
2184 Os.linux, Os.macosx, Os.ios, Os.windows => (try openSelfExe()).close(),
2219 Os.linux, Os.macosx, Os.ios, Os.windows, Os.freebsd => (try openSelfExe()).close(),
21852220 else => return error.SkipZigTest, // Unsupported OS.
21862221 }
21872222}
......@@ -2212,6 +2247,7 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 {
22122247pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
22132248 switch (builtin.os) {
22142249 Os.linux => return readLink(out_buffer, "/proc/self/exe"),
2250 Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"),
22152251 Os.windows => {
22162252 var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined;
22172253 const utf16le_slice = try selfExePathW(&utf16le_buf);
......@@ -2250,7 +2286,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 {
22502286 // will not return null.
22512287 return path.dirname(full_exe_path).?;
22522288 },
2253 Os.windows, Os.macosx, Os.ios => {
2289 Os.windows, Os.macosx, Os.ios, Os.freebsd => {
22542290 const self_exe_path = try selfExePath(out_buffer);
22552291 // Assume that the OS APIs return absolute paths, and therefore dirname
22562292 // will not return null.
......@@ -3095,10 +3131,13 @@ pub const CpuCountError = error{
30953131
30963132pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
30973133 switch (builtin.os) {
3098 builtin.Os.macosx => {
3134 builtin.Os.macosx, builtin.Os.freebsd => {
30993135 var count: c_int = undefined;
31003136 var count_len: usize = @sizeOf(c_int);
3101 const rc = posix.sysctlbyname(c"hw.logicalcpu", @ptrCast(*c_void, &count), &count_len, null, 0);
3137 const rc = posix.sysctlbyname(switch (builtin.os) {
3138 builtin.Os.macosx => c"hw.logicalcpu",
3139 else => c"hw.ncpu",
3140 }, @ptrCast(*c_void, &count), &count_len, null, 0);
31023141 const err = posix.getErrno(rc);
31033142 switch (err) {
31043143 0 => return @intCast(usize, count),
std/os/linux/index.zig+56-47
......@@ -703,7 +703,7 @@ pub fn dup2(old: i32, new: i32) usize {
703703}
704704
705705pub fn dup3(old: i32, new: i32, flags: u32) usize {
706 return syscall3(SYS_dup3, @intCast(usize, old), @intCast(usize, new), flags);
706 return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), flags);
707707}
708708
709709// TODO https://github.com/ziglang/zig/issues/265
......@@ -747,7 +747,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {
747747}
748748
749749pub fn getdents64(fd: i32, dirp: [*]u8, count: usize) usize {
750 return syscall3(SYS_getdents64, @intCast(usize, fd), @ptrToInt(dirp), count);
750 return syscall3(SYS_getdents64, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count);
751751}
752752
753753pub fn inotify_init1(flags: u32) usize {
......@@ -755,16 +755,16 @@ pub fn inotify_init1(flags: u32) usize {
755755}
756756
757757pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize {
758 return syscall3(SYS_inotify_add_watch, @intCast(usize, fd), @ptrToInt(pathname), mask);
758 return syscall3(SYS_inotify_add_watch, @bitCast(usize, isize(fd)), @ptrToInt(pathname), mask);
759759}
760760
761761pub fn inotify_rm_watch(fd: i32, wd: i32) usize {
762 return syscall2(SYS_inotify_rm_watch, @intCast(usize, fd), @intCast(usize, wd));
762 return syscall2(SYS_inotify_rm_watch, @bitCast(usize, isize(fd)), @bitCast(usize, isize(wd)));
763763}
764764
765765pub fn isatty(fd: i32) bool {
766766 var wsz: winsize = undefined;
767 return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
767 return syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
768768}
769769
770770// TODO https://github.com/ziglang/zig/issues/265
......@@ -774,7 +774,7 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz
774774
775775// TODO https://github.com/ziglang/zig/issues/265
776776pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
777 return syscall4(SYS_readlinkat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
777 return syscall4(SYS_readlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
778778}
779779
780780// TODO https://github.com/ziglang/zig/issues/265
......@@ -784,7 +784,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {
784784
785785// TODO https://github.com/ziglang/zig/issues/265
786786pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize {
787 return syscall3(SYS_mkdirat, @intCast(usize, dirfd), @ptrToInt(path), mode);
787 return syscall3(SYS_mkdirat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);
788788}
789789
790790// TODO https://github.com/ziglang/zig/issues/265
......@@ -803,7 +803,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize {
803803}
804804
805805pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
806 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset));
806 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset));
807807}
808808
809809pub fn munmap(address: usize, length: usize) usize {
......@@ -811,23 +811,23 @@ pub fn munmap(address: usize, length: usize) usize {
811811}
812812
813813pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
814 return syscall3(SYS_read, @intCast(usize, fd), @ptrToInt(buf), count);
814 return syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
815815}
816816
817817pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
818 return syscall4(SYS_preadv, @intCast(usize, fd), @ptrToInt(iov), count, offset);
818 return syscall4(SYS_preadv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset);
819819}
820820
821821pub fn readv(fd: i32, iov: [*]const iovec, count: usize) usize {
822 return syscall3(SYS_readv, @intCast(usize, fd), @ptrToInt(iov), count);
822 return syscall3(SYS_readv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);
823823}
824824
825825pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
826 return syscall3(SYS_writev, @intCast(usize, fd), @ptrToInt(iov), count);
826 return syscall3(SYS_writev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);
827827}
828828
829829pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
830 return syscall4(SYS_pwritev, @intCast(usize, fd), @ptrToInt(iov), count, offset);
830 return syscall4(SYS_pwritev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset);
831831}
832832
833833// TODO https://github.com/ziglang/zig/issues/265
......@@ -842,12 +842,12 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
842842
843843// TODO https://github.com/ziglang/zig/issues/265
844844pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize {
845 return syscall3(SYS_symlinkat, @ptrToInt(existing), @intCast(usize, newfd), @ptrToInt(newpath));
845 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(newfd)), @ptrToInt(newpath));
846846}
847847
848848// TODO https://github.com/ziglang/zig/issues/265
849849pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
850 return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset);
850 return syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
851851}
852852
853853// TODO https://github.com/ziglang/zig/issues/265
......@@ -856,7 +856,7 @@ pub fn access(path: [*]const u8, mode: u32) usize {
856856}
857857
858858pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize {
859 return syscall3(SYS_faccessat, @intCast(usize, dirfd), @ptrToInt(path), mode);
859 return syscall3(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);
860860}
861861
862862pub fn pipe(fd: *[2]i32) usize {
......@@ -868,11 +868,11 @@ pub fn pipe2(fd: *[2]i32, flags: u32) usize {
868868}
869869
870870pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
871 return syscall3(SYS_write, @intCast(usize, fd), @ptrToInt(buf), count);
871 return syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
872872}
873873
874874pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
875 return syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset);
875 return syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
876876}
877877
878878// TODO https://github.com/ziglang/zig/issues/265
......@@ -882,7 +882,7 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {
882882
883883// TODO https://github.com/ziglang/zig/issues/265
884884pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize {
885 return syscall5(SYS_renameat2, @intCast(usize, oldfd), @ptrToInt(oldpath), @intCast(usize, newfd), @ptrToInt(newpath), flags);
885 return syscall5(SYS_renameat2, @bitCast(usize, isize(oldfd)), @ptrToInt(oldpath), @bitCast(usize, isize(newfd)), @ptrToInt(newpath), flags);
886886}
887887
888888// TODO https://github.com/ziglang/zig/issues/265
......@@ -897,7 +897,8 @@ pub fn create(path: [*]const u8, perm: usize) usize {
897897
898898// TODO https://github.com/ziglang/zig/issues/265
899899pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize {
900 return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode);
900 // dirfd could be negative, for example AT_FDCWD is -100
901 return syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode);
901902}
902903
903904/// See also `clone` (from the arch-specific include)
......@@ -911,11 +912,11 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
911912}
912913
913914pub fn close(fd: i32) usize {
914 return syscall1(SYS_close, @intCast(usize, fd));
915 return syscall1(SYS_close, @bitCast(usize, isize(fd)));
915916}
916917
917918pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {
918 return syscall3(SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos);
919 return syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), ref_pos);
919920}
920921
921922pub fn exit(status: i32) noreturn {
......@@ -933,7 +934,7 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
933934}
934935
935936pub fn kill(pid: i32, sig: i32) usize {
936 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @intCast(usize, sig));
937 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig)));
937938}
938939
939940// TODO https://github.com/ziglang/zig/issues/265
......@@ -943,7 +944,7 @@ pub fn unlink(path: [*]const u8) usize {
943944
944945// TODO https://github.com/ziglang/zig/issues/265
945946pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
946 return syscall3(SYS_unlinkat, @intCast(usize, dirfd), @ptrToInt(path), flags);
947 return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);
947948}
948949
949950pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
......@@ -1120,8 +1121,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len;
11201121pub fn raise(sig: i32) usize {
11211122 var set: sigset_t = undefined;
11221123 blockAppSignals(&set);
1123 const tid = @intCast(i32, syscall0(SYS_gettid));
1124 const ret = syscall2(SYS_tkill, @intCast(usize, tid), @intCast(usize, sig));
1124 const tid = syscall0(SYS_gettid);
1125 const ret = syscall2(SYS_tkill, tid, @bitCast(usize, isize(sig)));
11251126 restoreSignals(&set);
11261127 return ret;
11271128}
......@@ -1189,11 +1190,11 @@ pub const iovec_const = extern struct {
11891190};
11901191
11911192pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
1192 return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len));
1193 return syscall3(SYS_getsockname, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));
11931194}
11941195
11951196pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
1196 return syscall3(SYS_getpeername, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len));
1197 return syscall3(SYS_getpeername, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));
11971198}
11981199
11991200pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
......@@ -1201,47 +1202,47 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
12011202}
12021203
12031204pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
1204 return syscall5(SYS_setsockopt, @intCast(usize, fd), level, optname, @intCast(usize, optval), @ptrToInt(optlen));
1205 return syscall5(SYS_setsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
12051206}
12061207
12071208pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
1208 return syscall5(SYS_getsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
1209 return syscall5(SYS_getsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
12091210}
12101211
12111212pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize {
1212 return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags);
1213 return syscall3(SYS_sendmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);
12131214}
12141215
12151216pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
1216 return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), len);
1217 return syscall3(SYS_connect, @bitCast(usize, isize(fd)), @ptrToInt(addr), len);
12171218}
12181219
12191220pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
1220 return syscall3(SYS_recvmsg, @intCast(usize, fd), @ptrToInt(msg), flags);
1221 return syscall3(SYS_recvmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);
12211222}
12221223
12231224pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
1224 return syscall6(SYS_recvfrom, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
1225 return syscall6(SYS_recvfrom, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
12251226}
12261227
12271228pub fn shutdown(fd: i32, how: i32) usize {
1228 return syscall2(SYS_shutdown, @intCast(usize, fd), @intCast(usize, how));
1229 return syscall2(SYS_shutdown, @bitCast(usize, isize(fd)), @bitCast(usize, isize(how)));
12291230}
12301231
12311232pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
1232 return syscall3(SYS_bind, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len));
1233 return syscall3(SYS_bind, @bitCast(usize, isize(fd)), @ptrToInt(addr), @intCast(usize, len));
12331234}
12341235
12351236pub fn listen(fd: i32, backlog: u32) usize {
1236 return syscall2(SYS_listen, @intCast(usize, fd), backlog);
1237 return syscall2(SYS_listen, @bitCast(usize, isize(fd)), backlog);
12371238}
12381239
12391240pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
1240 return syscall6(SYS_sendto, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
1241 return syscall6(SYS_sendto, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
12411242}
12421243
12431244pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
1244 return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(*fd[0]));
1245 return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]));
12451246}
12461247
12471248pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
......@@ -1249,11 +1250,11 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
12491250}
12501251
12511252pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {
1252 return syscall4(SYS_accept4, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len), flags);
1253 return syscall4(SYS_accept4, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len), flags);
12531254}
12541255
12551256pub fn fstat(fd: i32, stat_buf: *Stat) usize {
1256 return syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf));
1257 return syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));
12571258}
12581259
12591260// TODO https://github.com/ziglang/zig/issues/265
......@@ -1268,7 +1269,7 @@ pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {
12681269
12691270// TODO https://github.com/ziglang/zig/issues/265
12701271pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize {
1271 return syscall4(SYS_fstatat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(stat_buf), flags);
1272 return syscall4(SYS_fstatat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
12721273}
12731274
12741275// TODO https://github.com/ziglang/zig/issues/265
......@@ -1355,7 +1356,7 @@ pub fn epoll_create1(flags: usize) usize {
13551356}
13561357
13571358pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {
1358 return syscall4(SYS_epoll_ctl, @intCast(usize, epoll_fd), @intCast(usize, op), @intCast(usize, fd), @ptrToInt(ev));
1359 return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));
13591360}
13601361
13611362pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
......@@ -1363,7 +1364,15 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout
13631364}
13641365
13651366pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {
1366 return syscall6(SYS_epoll_pwait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout), @ptrToInt(sigmask), @sizeOf(sigset_t));
1367 return syscall6(
1368 SYS_epoll_pwait,
1369 @bitCast(usize, isize(epoll_fd)),
1370 @ptrToInt(events),
1371 @intCast(usize, maxevents),
1372 @bitCast(usize, isize(timeout)),
1373 @ptrToInt(sigmask),
1374 @sizeOf(sigset_t),
1375 );
13671376}
13681377
13691378pub fn eventfd(count: u32, flags: u32) usize {
......@@ -1371,7 +1380,7 @@ pub fn eventfd(count: u32, flags: u32) usize {
13711380}
13721381
13731382pub fn timerfd_create(clockid: i32, flags: u32) usize {
1374 return syscall2(SYS_timerfd_create, @intCast(usize, clockid), flags);
1383 return syscall2(SYS_timerfd_create, @bitCast(usize, isize(clockid)), flags);
13751384}
13761385
13771386pub const itimerspec = extern struct {
......@@ -1380,11 +1389,11 @@ pub const itimerspec = extern struct {
13801389};
13811390
13821391pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
1383 return syscall2(SYS_timerfd_gettime, @intCast(usize, fd), @ptrToInt(curr_value));
1392 return syscall2(SYS_timerfd_gettime, @bitCast(usize, isize(fd)), @ptrToInt(curr_value));
13841393}
13851394
13861395pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
1387 return syscall4(SYS_timerfd_settime, @intCast(usize, fd), flags, @ptrToInt(new_value), @ptrToInt(old_value));
1396 return syscall4(SYS_timerfd_settime, @bitCast(usize, isize(fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value));
13881397}
13891398
13901399pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
std/os/path.zig+12-2
......@@ -1093,6 +1093,7 @@ pub const RealError = error{
10931093 NoSpaceLeft,
10941094 FileSystem,
10951095 BadPathName,
1096 DeviceBusy,
10961097
10971098 /// On Windows, file paths must be valid Unicode.
10981099 InvalidUtf8,
......@@ -1183,11 +1184,20 @@ pub fn realC(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: [*]const u8) RealErro
11831184 const fd = try os.posixOpenC(pathname, posix.O_PATH | posix.O_NONBLOCK | posix.O_CLOEXEC, 0);
11841185 defer os.close(fd);
11851186
1186 var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;
1187 var buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
11871188 const proc_path = fmt.bufPrint(buf[0..], "/proc/self/fd/{}\x00", fd) catch unreachable;
11881189
11891190 return os.readLinkC(out_buffer, proc_path.ptr);
11901191 },
1192 Os.freebsd => { // XXX requires fdescfs
1193 const fd = try os.posixOpenC(pathname, posix.O_PATH | posix.O_NONBLOCK | posix.O_CLOEXEC, 0);
1194 defer os.close(fd);
1195
1196 var buf: ["/dev/fd/-2147483648\x00".len]u8 = undefined;
1197 const proc_path = fmt.bufPrint(buf[0..], "/dev/fd/{}\x00", fd) catch unreachable;
1198
1199 return os.readLinkC(out_buffer, proc_path.ptr);
1200 },
11911201 else => @compileError("TODO implement os.path.real for " ++ @tagName(builtin.os)),
11921202 }
11931203}
......@@ -1202,7 +1212,7 @@ pub fn real(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: []const u8) RealError!
12021212 const pathname_w = try windows_util.sliceToPrefixedFileW(pathname);
12031213 return realW(out_buffer, &pathname_w);
12041214 },
1205 Os.macosx, Os.ios, Os.linux => {
1215 Os.macosx, Os.ios, Os.linux, Os.freebsd => {
12061216 const pathname_c = try os.toPosixPath(pathname);
12071217 return realC(out_buffer, &pathname_c);
12081218 },
std/os/windows/kernel32.zig+3-3
......@@ -50,7 +50,7 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi
5050pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
5151pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;
5252
53pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL;
53pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;
5454
5555pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
5656
......@@ -63,9 +63,9 @@ pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lp
6363pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;
6464pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD;
6565
66pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
66pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16;
6767
68pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
68pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD;
6969
7070pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;
7171
std/os/zen.zig+11-11
......@@ -12,20 +12,20 @@ pub const Message = struct {
1212 args: [5]usize,
1313 payload: ?[]const u8,
1414
15 pub fn from(mailbox_id: *const MailboxId) Message {
15 pub fn from(mailbox_id: MailboxId) Message {
1616 return Message{
1717 .sender = MailboxId.Undefined,
18 .receiver = mailbox_id.*,
18 .receiver = mailbox_id,
1919 .code = undefined,
2020 .args = undefined,
2121 .payload = null,
2222 };
2323 }
2424
25 pub fn to(mailbox_id: *const MailboxId, msg_code: usize, args: ...) Message {
25 pub fn to(mailbox_id: MailboxId, msg_code: usize, args: ...) Message {
2626 var message = Message{
2727 .sender = MailboxId.This,
28 .receiver = mailbox_id.*,
28 .receiver = mailbox_id,
2929 .code = msg_code,
3030 .args = undefined,
3131 .payload = null,
......@@ -40,14 +40,14 @@ pub const Message = struct {
4040 return message;
4141 }
4242
43 pub fn as(self: *const Message, sender: *const MailboxId) Message {
44 var message = self.*;
45 message.sender = sender.*;
43 pub fn as(self: Message, sender: MailboxId) Message {
44 var message = self;
45 message.sender = sender;
4646 return message;
4747 }
4848
49 pub fn withPayload(self: *const Message, payload: []const u8) Message {
50 var message = self.*;
49 pub fn withPayload(self: Message, payload: []const u8) Message {
50 var message = self;
5151 message.payload = payload;
5252 return message;
5353 }
......@@ -93,7 +93,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
9393 STDIN_FILENO => {
9494 var i: usize = 0;
9595 while (i < count) : (i += 1) {
96 send(Message.to(Server.Keyboard, 0));
96 send(&Message.to(Server.Keyboard, 0));
9797
9898 // FIXME: we should be certain that we are receiving from Keyboard.
9999 var message = Message.from(MailboxId.This);
......@@ -111,7 +111,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
111111pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
112112 switch (fd) {
113113 STDOUT_FILENO, STDERR_FILENO => {
114 send(Message.to(Server.Terminal, 1).withPayload(buf[0..count]));
114 send(&Message.to(Server.Terminal, 1).withPayload(buf[0..count]));
115115 },
116116 else => unreachable,
117117 }
std/pdb.zig+4-3
......@@ -34,6 +34,7 @@ pub const DbiStreamHeader = packed struct {
3434};
3535
3636pub const SectionContribEntry = packed struct {
37 /// COFF Section index, 1-based
3738 Section: u16,
3839 Padding1: [2]u8,
3940 Offset: u32,
......@@ -507,11 +508,11 @@ const Msf = struct {
507508 allocator,
508509 );
509510
510 const stream_count = try self.directory.stream.readIntLe(u32);
511 const stream_count = try self.directory.stream.readIntLittle(u32);
511512
512513 const stream_sizes = try allocator.alloc(u32, stream_count);
513514 for (stream_sizes) |*s| {
514 const size = try self.directory.stream.readIntLe(u32);
515 const size = try self.directory.stream.readIntLittle(u32);
515516 s.* = blockCountFromSize(size, superblock.BlockSize);
516517 }
517518
......@@ -602,7 +603,7 @@ const MsfStream = struct {
602603
603604 var i: u32 = 0;
604605 while (i < block_count) : (i += 1) {
605 stream.blocks[i] = try in.readIntLe(u32);
606 stream.blocks[i] = try in.readIntLittle(u32);
606607 }
607608
608609 return stream;
std/rand/index.zig+160-41
......@@ -5,7 +5,7 @@
55// ```
66// var buf: [8]u8 = undefined;
77// try std.os.getRandomBytes(buf[0..]);
8// const seed = mem.readIntLE(u64, buf[0..8]);
8// const seed = mem.readIntSliceLittle(u64, buf[0..8]);
99//
1010// var r = DefaultPrng.init(seed);
1111//
......@@ -52,11 +52,24 @@ pub const Random = struct {
5252 // use LE instead of native endian for better portability maybe?
5353 // TODO: endian portability is pointless if the underlying prng isn't endian portable.
5454 // TODO: document the endian portability of this library.
55 const byte_aligned_result = mem.readIntLE(ByteAlignedT, rand_bytes);
55 const byte_aligned_result = mem.readIntSliceLittle(ByteAlignedT, rand_bytes);
5656 const unsigned_result = @truncate(UnsignedT, byte_aligned_result);
5757 return @bitCast(T, unsigned_result);
5858 }
5959
60 /// Constant-time implementation off ::uintLessThan.
61 /// The results of this function may be biased.
62 pub fn uintLessThanBiased(r: *Random, comptime T: type, less_than: T) T {
63 comptime assert(T.is_signed == false);
64 comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation!
65 assert(0 < less_than);
66 if (T.bit_count <= 32) {
67 return @intCast(T, limitRangeBiased(u32, r.int(u32), less_than));
68 } else {
69 return @intCast(T, limitRangeBiased(u64, r.int(u64), less_than));
70 }
71 }
72
6073 /// Returns an evenly distributed random unsigned integer `0 <= i < less_than`.
6174 /// This function assumes that the underlying ::fillFn produces evenly distributed values.
6275 /// Within this assumption, the runtime of this function is exponentially distributed.
......@@ -64,27 +77,52 @@ pub const Random = struct {
6477 /// the runtime of this function would technically be unbounded.
6578 /// However, if ::fillFn is backed by any evenly distributed pseudo random number generator,
6679 /// this function is guaranteed to return.
67 /// If you need deterministic runtime bounds, consider instead using `r.int(T) % less_than`,
68 /// which will usually be biased toward smaller values.
80 /// If you need deterministic runtime bounds, use `::uintLessThanBiased`.
6981 pub fn uintLessThan(r: *Random, comptime T: type, less_than: T) T {
70 assert(T.is_signed == false);
82 comptime assert(T.is_signed == false);
83 comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation!
7184 assert(0 < less_than);
72
73 const last_group_size_minus_one: T = maxInt(T) % less_than;
74 if (last_group_size_minus_one == less_than - 1) {
75 // less_than is a power of two.
76 assert(math.floorPowerOfTwo(T, less_than) == less_than);
77 // There is no retry zone. The optimal retry_zone_start would be maxInt(T) + 1.
78 return r.int(T) % less_than;
85 // Small is typically u32
86 const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32);
87 // Large is typically u64
88 const Large = @IntType(false, Small.bit_count * 2);
89
90 // adapted from:
91 // http://www.pcg-random.org/posts/bounded-rands.html
92 // "Lemire's (with an extra tweak from me)"
93 var x: Small = r.int(Small);
94 var m: Large = Large(x) * Large(less_than);
95 var l: Small = @truncate(Small, m);
96 if (l < less_than) {
97 // TODO: workaround for https://github.com/ziglang/zig/issues/1770
98 // should be:
99 // var t: Small = -%less_than;
100 var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), Small(less_than)));
101
102 if (t >= less_than) {
103 t -= less_than;
104 if (t >= less_than) {
105 t %= less_than;
106 }
107 }
108 while (l < t) {
109 x = r.int(Small);
110 m = Large(x) * Large(less_than);
111 l = @truncate(Small, m);
112 }
79113 }
80 const retry_zone_start = maxInt(T) - last_group_size_minus_one;
114 return @intCast(T, m >> Small.bit_count);
115 }
81116
82 while (true) {
83 const rand_val = r.int(T);
84 if (rand_val < retry_zone_start) {
85 return rand_val % less_than;
86 }
117 /// Constant-time implementation off ::uintAtMost.
118 /// The results of this function may be biased.
119 pub fn uintAtMostBiased(r: *Random, comptime T: type, at_most: T) T {
120 assert(T.is_signed == false);
121 if (at_most == maxInt(T)) {
122 // have the full range
123 return r.int(T);
87124 }
125 return r.uintLessThanBiased(T, at_most + 1);
88126 }
89127
90128 /// Returns an evenly distributed random unsigned integer `0 <= i <= at_most`.
......@@ -99,6 +137,23 @@ pub const Random = struct {
99137 return r.uintLessThan(T, at_most + 1);
100138 }
101139
140 /// Constant-time implementation off ::intRangeLessThan.
141 /// The results of this function may be biased.
142 pub fn intRangeLessThanBiased(r: *Random, comptime T: type, at_least: T, less_than: T) T {
143 assert(at_least < less_than);
144 if (T.is_signed) {
145 // Two's complement makes this math pretty easy.
146 const UnsignedT = @IntType(false, T.bit_count);
147 const lo = @bitCast(UnsignedT, at_least);
148 const hi = @bitCast(UnsignedT, less_than);
149 const result = lo +% r.uintLessThanBiased(UnsignedT, hi -% lo);
150 return @bitCast(T, result);
151 } else {
152 // The signed implementation would work fine, but we can use stricter arithmetic operators here.
153 return at_least + r.uintLessThanBiased(T, less_than - at_least);
154 }
155 }
156
102157 /// Returns an evenly distributed random integer `at_least <= i < less_than`.
103158 /// See ::uintLessThan, which this function uses in most cases,
104159 /// for commentary on the runtime of this function.
......@@ -117,6 +172,23 @@ pub const Random = struct {
117172 }
118173 }
119174
175 /// Constant-time implementation off ::intRangeAtMostBiased.
176 /// The results of this function may be biased.
177 pub fn intRangeAtMostBiased(r: *Random, comptime T: type, at_least: T, at_most: T) T {
178 assert(at_least <= at_most);
179 if (T.is_signed) {
180 // Two's complement makes this math pretty easy.
181 const UnsignedT = @IntType(false, T.bit_count);
182 const lo = @bitCast(UnsignedT, at_least);
183 const hi = @bitCast(UnsignedT, at_most);
184 const result = lo +% r.uintAtMostBiased(UnsignedT, hi -% lo);
185 return @bitCast(T, result);
186 } else {
187 // The signed implementation would work fine, but we can use stricter arithmetic operators here.
188 return at_least + r.uintAtMostBiased(T, at_most - at_least);
189 }
190 }
191
120192 /// Returns an evenly distributed random integer `at_least <= i <= at_most`.
121193 /// See ::uintLessThan, which this function uses in most cases,
122194 /// for commentary on the runtime of this function.
......@@ -135,15 +207,11 @@ pub const Random = struct {
135207 }
136208 }
137209
138 /// Return a random integer/boolean type.
139210 /// TODO: deprecated. use ::boolean or ::int instead.
140211 pub fn scalar(r: *Random, comptime T: type) T {
141 if (T == bool) return r.boolean();
142 return r.int(T);
212 return if (T == bool) r.boolean() else r.int(T);
143213 }
144214
145 /// Return a random integer with even distribution between `start`
146 /// inclusive and `end` exclusive. `start` must be less than `end`.
147215 /// TODO: deprecated. renamed to ::intRangeLessThan
148216 pub fn range(r: *Random, comptime T: type, start: T, end: T) T {
149217 return r.intRangeLessThan(T, start, end);
......@@ -206,6 +274,20 @@ pub const Random = struct {
206274 }
207275};
208276
277/// Convert a random integer 0 <= random_int <= maxValue(T),
278/// into an integer 0 <= result < less_than.
279/// This function introduces a minor bias.
280pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
281 comptime assert(T.is_signed == false);
282 const T2 = @IntType(false, T.bit_count * 2);
283
284 // adapted from:
285 // http://www.pcg-random.org/posts/bounded-rands.html
286 // "Integer Multiplication (Biased)"
287 var m: T2 = T2(random_int) * T2(less_than);
288 return @intCast(T, m >> T.bit_count);
289}
290
209291const SequentialPrng = struct {
210292 const Self = @This();
211293 random: Random,
......@@ -294,10 +376,19 @@ fn testRandomIntLessThan() void {
294376 var r = SequentialPrng.init();
295377 r.next_value = 0xff;
296378 assert(r.random.uintLessThan(u8, 4) == 3);
297 r.next_value = 0xff;
298 assert(r.random.uintLessThan(u8, 3) == 0);
379 assert(r.next_value == 0);
380 assert(r.random.uintLessThan(u8, 4) == 0);
299381 assert(r.next_value == 1);
300382
383 r.next_value = 0;
384 assert(r.random.uintLessThan(u64, 32) == 0);
385
386 // trigger the bias rejection code path
387 r.next_value = 0;
388 assert(r.random.uintLessThan(u8, 3) == 0);
389 // verify we incremented twice
390 assert(r.next_value == 2);
391
301392 r.next_value = 0xff;
302393 assert(r.random.intRangeLessThan(u8, 0, 0x80) == 0x7f);
303394 r.next_value = 0xff;
......@@ -310,17 +401,10 @@ fn testRandomIntLessThan() void {
310401 r.next_value = 0xff;
311402 assert(r.random.intRangeLessThan(i8, -0x80, 0) == -1);
312403
313 r.next_value = 0xff;
314 assert(r.random.intRangeLessThan(i64, -0x8000000000000000, 0) == -1);
315404 r.next_value = 0xff;
316405 assert(r.random.intRangeLessThan(i3, -4, 0) == -1);
317406 r.next_value = 0xff;
318407 assert(r.random.intRangeLessThan(i3, -2, 2) == 1);
319
320 // test retrying and eventually getting a good value
321 // start just out of bounds
322 r.next_value = 0x81;
323 assert(r.random.uintLessThan(u8, 0x81) == 0);
324408}
325409
326410test "Random intAtMost" {
......@@ -332,9 +416,14 @@ fn testRandomIntAtMost() void {
332416 var r = SequentialPrng.init();
333417 r.next_value = 0xff;
334418 assert(r.random.uintAtMost(u8, 3) == 3);
335 r.next_value = 0xff;
419 assert(r.next_value == 0);
420 assert(r.random.uintAtMost(u8, 3) == 0);
421
422 // trigger the bias rejection code path
423 r.next_value = 0;
336424 assert(r.random.uintAtMost(u8, 2) == 0);
337 assert(r.next_value == 1);
425 // verify we incremented twice
426 assert(r.next_value == 2);
338427
339428 r.next_value = 0xff;
340429 assert(r.random.intRangeAtMost(u8, 0, 0x7f) == 0x7f);
......@@ -348,17 +437,43 @@ fn testRandomIntAtMost() void {
348437 r.next_value = 0xff;
349438 assert(r.random.intRangeAtMost(i8, -0x80, -1) == -1);
350439
351 r.next_value = 0xff;
352 assert(r.random.intRangeAtMost(i64, -0x8000000000000000, -1) == -1);
353440 r.next_value = 0xff;
354441 assert(r.random.intRangeAtMost(i3, -4, -1) == -1);
355442 r.next_value = 0xff;
356443 assert(r.random.intRangeAtMost(i3, -2, 1) == 1);
357444
358 // test retrying and eventually getting a good value
359 // start just out of bounds
360 r.next_value = 0x81;
361 assert(r.random.uintAtMost(u8, 0x80) == 0);
445 assert(r.random.uintAtMost(u0, 0) == 0);
446}
447
448test "Random Biased" {
449 var r = DefaultPrng.init(0);
450 // Not thoroughly checking the logic here.
451 // Just want to execute all the paths with different types.
452
453 assert(r.random.uintLessThanBiased(u1, 1) == 0);
454 assert(r.random.uintLessThanBiased(u32, 10) < 10);
455 assert(r.random.uintLessThanBiased(u64, 20) < 20);
456
457 assert(r.random.uintAtMostBiased(u0, 0) == 0);
458 assert(r.random.uintAtMostBiased(u1, 0) <= 0);
459 assert(r.random.uintAtMostBiased(u32, 10) <= 10);
460 assert(r.random.uintAtMostBiased(u64, 20) <= 20);
461
462 assert(r.random.intRangeLessThanBiased(u1, 0, 1) == 0);
463 assert(r.random.intRangeLessThanBiased(i1, -1, 0) == -1);
464 assert(r.random.intRangeLessThanBiased(u32, 10, 20) >= 10);
465 assert(r.random.intRangeLessThanBiased(i32, 10, 20) >= 10);
466 assert(r.random.intRangeLessThanBiased(u64, 20, 40) >= 20);
467 assert(r.random.intRangeLessThanBiased(i64, 20, 40) >= 20);
468
469 // uncomment for broken module error:
470 //assert(r.random.intRangeAtMostBiased(u0, 0, 0) == 0);
471 assert(r.random.intRangeAtMostBiased(u1, 0, 1) >= 0);
472 assert(r.random.intRangeAtMostBiased(i1, -1, 0) >= -1);
473 assert(r.random.intRangeAtMostBiased(u32, 10, 20) >= 10);
474 assert(r.random.intRangeAtMostBiased(i32, 10, 20) >= 10);
475 assert(r.random.intRangeAtMostBiased(u64, 20, 40) >= 20);
476 assert(r.random.intRangeAtMostBiased(i64, 20, 40) >= 20);
362477}
363478
364479// Generator to extend 64-bit seed values into longer sequences.
......@@ -870,12 +985,16 @@ test "Random range" {
870985}
871986
872987fn testRange(r: *Random, start: i8, end: i8) void {
988 testRangeBias(r, start, end, true);
989 testRangeBias(r, start, end, false);
990}
991fn testRangeBias(r: *Random, start: i8, end: i8, biased: bool) void {
873992 const count = @intCast(usize, i32(end) - i32(start));
874993 var values_buffer = []bool{false} ** 0x100;
875994 const values = values_buffer[0..count];
876995 var i: usize = 0;
877996 while (i < count) {
878 const value: i32 = r.intRangeLessThan(i8, start, end);
997 const value: i32 = if (biased) r.intRangeLessThanBiased(i8, start, end) else r.intRangeLessThan(i8, start, end);
879998 const index = @intCast(usize, value - start);
880999 if (!values[index]) {
8811000 i += 1;
std/rand/ziggurat.zig+1-1
......@@ -12,7 +12,7 @@ const std = @import("../index.zig");
1212const math = std.math;
1313const Random = std.rand.Random;
1414
15pub fn next_f64(random: *Random, comptime tables: *const ZigTable) f64 {
15pub fn next_f64(random: *Random, comptime tables: ZigTable) f64 {
1616 while (true) {
1717 // We manually construct a float from parts as we can avoid an extra random lookup here by
1818 // using the unused exponent for the lookup table entry.
std/segmented_list.zig+5
......@@ -201,6 +201,11 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
201201 self.dynamic_segments = self.allocator.shrink([*]T, self.dynamic_segments, new_cap_shelf_count);
202202 }
203203
204 pub fn shrink(self: *Self, new_len: usize) void {
205 assert(new_len <= self.len);
206 self.len = new_len;
207 }
208
204209 pub fn uncheckedAt(self: var, index: usize) AtType(@typeOf(self)) {
205210 if (index < prealloc_item_count) {
206211 return &self.prealloc_segment[index];
std/special/bootstrap.zig+14-4
......@@ -20,10 +20,17 @@ comptime {
2020
2121nakedcc fn _start() noreturn {
2222 switch (builtin.arch) {
23 builtin.Arch.x86_64 => {
24 argc_ptr = asm ("lea (%%rsp), %[argc]"
25 : [argc] "=r" (-> [*]usize)
26 );
23 builtin.Arch.x86_64 => switch (builtin.os) {
24 builtin.Os.freebsd => {
25 argc_ptr = asm ("lea (%%rdi), %[argc]"
26 : [argc] "=r" (-> [*]usize)
27 );
28 },
29 else => {
30 argc_ptr = asm ("lea (%%rsp), %[argc]"
31 : [argc] "=r" (-> [*]usize)
32 );
33 },
2734 },
2835 builtin.Arch.i386 => {
2936 argc_ptr = asm ("lea (%%esp), %[argc]"
......@@ -50,6 +57,9 @@ extern fn WinMainCRTStartup() noreturn {
5057
5158// TODO https://github.com/ziglang/zig/issues/265
5259fn posixCallMainAndExit() noreturn {
60 if (builtin.os == builtin.Os.freebsd) {
61 @setAlignStack(16);
62 }
5363 const argc = argc_ptr[0];
5464 const argv = @ptrCast([*][*]u8, argc_ptr + 1);
5565
std/special/build_runner.zig-1
......@@ -164,7 +164,6 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
164164 \\
165165 \\General Options:
166166 \\ --help Print this help and exit
167 \\ --init Generate a build.zig template
168167 \\ --verbose Print commands before executing them
169168 \\ --prefix [path] Override default install prefix
170169 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
std/special/compiler_rt/fixdfdi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixdfdi(a: f64) i64 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f64, i64, a);
7}
8
9test "import fixdfdi" {
10 _ = @import("fixdfdi_test.zig");
11}
std/special/compiler_rt/fixdfdi_test.zig created+66
......@@ -0,0 +1,66 @@
1const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixdfdi(a: f64, expected: i64) void {
8 const x = __fixdfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
10 assert(x == expected);
11}
12
13test "fixdfdi" {
14 //warn("\n");
15
16 test__fixdfdi(-math.f64_max, math.minInt(i64));
17
18 test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
19 test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
20
21 test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000);
22 test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
23 test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
24
25 test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000);
26 test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000);
27 test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
28 test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
29
30 test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
31 test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
32
33 test__fixdfdi(-2.01, -2);
34 test__fixdfdi(-2.0, -2);
35 test__fixdfdi(-1.99, -1);
36 test__fixdfdi(-1.0, -1);
37 test__fixdfdi(-0.99, 0);
38 test__fixdfdi(-0.5, 0);
39 test__fixdfdi(-math.f64_min, 0);
40 test__fixdfdi(0.0, 0);
41 test__fixdfdi(math.f64_min, 0);
42 test__fixdfdi(0.5, 0);
43 test__fixdfdi(0.99, 0);
44 test__fixdfdi(1.0, 1);
45 test__fixdfdi(1.5, 1);
46 test__fixdfdi(1.99, 1);
47 test__fixdfdi(2.0, 2);
48 test__fixdfdi(2.01, 2);
49
50 test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
51 test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
52
53 test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
54 test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
55 test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
56 test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
57
58 test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
59 test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
60 test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
61
62 test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
63 test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
64
65 test__fixdfdi(math.f64_max, math.maxInt(i64));
66}
std/special/compiler_rt/fixdfsi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixdfsi(a: f64) i32 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f64, i32, a);
7}
8
9test "import fixdfsi" {
10 _ = @import("fixdfsi_test.zig");
11}
std/special/compiler_rt/fixdfsi_test.zig created+74
......@@ -0,0 +1,74 @@
1const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixdfsi(a: f64, expected: i32) void {
8 const x = __fixdfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
10 assert(x == expected);
11}
12
13test "fixdfsi" {
14 //warn("\n");
15
16 test__fixdfsi(-math.f64_max, math.minInt(i32));
17
18 test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
19 test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
20
21 test__fixdfsi(-0x1.0000000000000p+127, -0x80000000);
22 test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
23 test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
24
25 test__fixdfsi(-0x1.0000000000001p+63, -0x80000000);
26 test__fixdfsi(-0x1.0000000000000p+63, -0x80000000);
27 test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
28 test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
29
30 test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000);
31 test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000);
32
33 test__fixdfsi(-0x1.000000p+31, -0x80000000);
34 test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
35 test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
36
37 test__fixdfsi(-2.01, -2);
38 test__fixdfsi(-2.0, -2);
39 test__fixdfsi(-1.99, -1);
40 test__fixdfsi(-1.0, -1);
41 test__fixdfsi(-0.99, 0);
42 test__fixdfsi(-0.5, 0);
43 test__fixdfsi(-math.f64_min, 0);
44 test__fixdfsi(0.0, 0);
45 test__fixdfsi(math.f64_min, 0);
46 test__fixdfsi(0.5, 0);
47 test__fixdfsi(0.99, 0);
48 test__fixdfsi(1.0, 1);
49 test__fixdfsi(1.5, 1);
50 test__fixdfsi(1.99, 1);
51 test__fixdfsi(2.0, 2);
52 test__fixdfsi(2.01, 2);
53
54 test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
55 test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
56 test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF);
57
58 test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
59 test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
60
61 test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
62 test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
63 test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
64 test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
65
66 test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
67 test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
68 test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
69
70 test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
71 test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
72
73 test__fixdfsi(math.f64_max, math.maxInt(i32));
74}
std/special/compiler_rt/fixdfti.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixdfti(a: f64) i128 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f64, i128, a);
7}
8
9test "import fixdfti" {
10 _ = @import("fixdfti_test.zig");
11}
std/special/compiler_rt/fixdfti_test.zig created+66
......@@ -0,0 +1,66 @@
1const __fixdfti = @import("fixdfti.zig").__fixdfti;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixdfti(a: f64, expected: i128) void {
8 const x = __fixdfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
10 assert(x == expected);
11}
12
13test "fixdfti" {
14 //warn("\n");
15
16 test__fixdfti(-math.f64_max, math.minInt(i128));
17
18 test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
19 test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
20
21 test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
22 test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
23 test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
24
25 test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800);
26 test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000);
27 test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
28 test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
29
30 test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
31 test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
32
33 test__fixdfti(-2.01, -2);
34 test__fixdfti(-2.0, -2);
35 test__fixdfti(-1.99, -1);
36 test__fixdfti(-1.0, -1);
37 test__fixdfti(-0.99, 0);
38 test__fixdfti(-0.5, 0);
39 test__fixdfti(-math.f64_min, 0);
40 test__fixdfti(0.0, 0);
41 test__fixdfti(math.f64_min, 0);
42 test__fixdfti(0.5, 0);
43 test__fixdfti(0.99, 0);
44 test__fixdfti(1.0, 1);
45 test__fixdfti(1.5, 1);
46 test__fixdfti(1.99, 1);
47 test__fixdfti(2.0, 2);
48 test__fixdfti(2.01, 2);
49
50 test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
51 test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
52
53 test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
54 test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
55 test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000);
56 test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800);
57
58 test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
59 test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
60 test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
61
62 test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
63 test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
64
65 test__fixdfti(math.f64_max, math.maxInt(i128));
66}
std/special/compiler_rt/fixint.zig created+74
......@@ -0,0 +1,74 @@
1const is_test = @import("builtin").is_test;
2const std = @import("std");
3const math = std.math;
4const Log2Int = std.math.Log2Int;
5const maxInt = std.math.maxInt;
6const minInt = std.math.minInt;
7
8const DBG = false;
9
10pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
11 @setRuntimeSafety(is_test);
12
13 const rep_t = switch (fp_t) {
14 f32 => u32,
15 f64 => u64,
16 f128 => u128,
17 else => unreachable,
18 };
19 const significandBits = switch (fp_t) {
20 f32 => 23,
21 f64 => 52,
22 f128 => 112,
23 else => unreachable,
24 };
25
26 const typeWidth = rep_t.bit_count;
27 const exponentBits = (typeWidth - significandBits - 1);
28 const signBit = (rep_t(1) << (significandBits + exponentBits));
29 const maxExponent = ((1 << exponentBits) - 1);
30 const exponentBias = (maxExponent >> 1);
31
32 const implicitBit = (rep_t(1) << significandBits);
33 const significandMask = (implicitBit - 1);
34
35 // Break a into sign, exponent, significand
36 const aRep: rep_t = @bitCast(rep_t, a);
37 const absMask = signBit - 1;
38 const aAbs: rep_t = aRep & absMask;
39
40 const negative = (aRep & signBit) != 0;
41 const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
42 const significand: rep_t = (aAbs & significandMask) | implicitBit;
43
44 // If exponent is negative, the uint_result is zero.
45 if (exponent < 0) return 0;
46
47 // The unsigned result needs to be large enough to handle an fixint_t or rep_t
48 const fixuint_t = @IntType(false, fixint_t.bit_count);
49 const UintResultType = if (fixint_t.bit_count > rep_t.bit_count) fixuint_t else rep_t;
50 var uint_result: UintResultType = undefined;
51
52 // If the value is too large for the integer type, saturate.
53 if (@intCast(usize, exponent) >= fixint_t.bit_count) {
54 return if (negative) fixint_t(minInt(fixint_t)) else fixint_t(maxInt(fixint_t));
55 }
56
57 // If 0 <= exponent < significandBits, right shift else left shift
58 if (exponent < significandBits) {
59 uint_result = @intCast(UintResultType, significand) >> @intCast(Log2Int(UintResultType), significandBits - exponent);
60 } else {
61 uint_result = @intCast(UintResultType, significand) << @intCast(Log2Int(UintResultType), exponent - significandBits);
62 }
63
64 // Cast to final signed result
65 if (negative) {
66 return if (uint_result >= -math.minInt(fixint_t)) math.minInt(fixint_t) else -@intCast(fixint_t, uint_result);
67 } else {
68 return if (uint_result >= math.maxInt(fixint_t)) math.maxInt(fixint_t) else @intCast(fixint_t, uint_result);
69 }
70}
71
72test "import fixint" {
73 _ = @import("fixint_test.zig");
74}
std/special/compiler_rt/fixint_test.zig created+152
......@@ -0,0 +1,152 @@
1const is_test = @import("builtin").is_test;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7const fixint = @import("fixint.zig").fixint;
8
9fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) void {
10 const x = fixint(fp_t, fixint_t, a);
11 //warn("a={} x={}:{x} expected={}:{x})\n", a, x, x, expected, expected);
12 assert(x == expected);
13}
14
15test "fixint.i1" {
16 test__fixint(f32, i1, -math.inf_f32, -1);
17 test__fixint(f32, i1, -math.f32_max, -1);
18 test__fixint(f32, i1, -2.0, -1);
19 test__fixint(f32, i1, -1.1, -1);
20 test__fixint(f32, i1, -1.0, -1);
21 test__fixint(f32, i1, -0.9, 0);
22 test__fixint(f32, i1, -0.1, 0);
23 test__fixint(f32, i1, -math.f32_min, 0);
24 test__fixint(f32, i1, -0.0, 0);
25 test__fixint(f32, i1, 0.0, 0);
26 test__fixint(f32, i1, math.f32_min, 0);
27 test__fixint(f32, i1, 0.1, 0);
28 test__fixint(f32, i1, 0.9, 0);
29 test__fixint(f32, i1, 1.0, 0);
30 test__fixint(f32, i1, 2.0, 0);
31 test__fixint(f32, i1, math.f32_max, 0);
32 test__fixint(f32, i1, math.inf_f32, 0);
33}
34
35test "fixint.i2" {
36 test__fixint(f32, i2, -math.inf_f32, -2);
37 test__fixint(f32, i2, -math.f32_max, -2);
38 test__fixint(f32, i2, -2.0, -2);
39 test__fixint(f32, i2, -1.9, -1);
40 test__fixint(f32, i2, -1.1, -1);
41 test__fixint(f32, i2, -1.0, -1);
42 test__fixint(f32, i2, -0.9, 0);
43 test__fixint(f32, i2, -0.1, 0);
44 test__fixint(f32, i2, -math.f32_min, 0);
45 test__fixint(f32, i2, -0.0, 0);
46 test__fixint(f32, i2, 0.0, 0);
47 test__fixint(f32, i2, math.f32_min, 0);
48 test__fixint(f32, i2, 0.1, 0);
49 test__fixint(f32, i2, 0.9, 0);
50 test__fixint(f32, i2, 1.0, 1);
51 test__fixint(f32, i2, 2.0, 1);
52 test__fixint(f32, i2, math.f32_max, 1);
53 test__fixint(f32, i2, math.inf_f32, 1);
54}
55
56test "fixint.i3" {
57 test__fixint(f32, i3, -math.inf_f32, -4);
58 test__fixint(f32, i3, -math.f32_max, -4);
59 test__fixint(f32, i3, -4.0, -4);
60 test__fixint(f32, i3, -3.0, -3);
61 test__fixint(f32, i3, -2.0, -2);
62 test__fixint(f32, i3, -1.9, -1);
63 test__fixint(f32, i3, -1.1, -1);
64 test__fixint(f32, i3, -1.0, -1);
65 test__fixint(f32, i3, -0.9, 0);
66 test__fixint(f32, i3, -0.1, 0);
67 test__fixint(f32, i3, -math.f32_min, 0);
68 test__fixint(f32, i3, -0.0, 0);
69 test__fixint(f32, i3, 0.0, 0);
70 test__fixint(f32, i3, math.f32_min, 0);
71 test__fixint(f32, i3, 0.1, 0);
72 test__fixint(f32, i3, 0.9, 0);
73 test__fixint(f32, i3, 1.0, 1);
74 test__fixint(f32, i3, 2.0, 2);
75 test__fixint(f32, i3, 3.0, 3);
76 test__fixint(f32, i3, 4.0, 3);
77 test__fixint(f32, i3, math.f32_max, 3);
78 test__fixint(f32, i3, math.inf_f32, 3);
79}
80
81test "fixint.i32" {
82 test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));
83 test__fixint(f64, i32, -math.f64_max, math.minInt(i32));
84 test__fixint(f64, i32, f64(math.minInt(i32)), math.minInt(i32));
85 test__fixint(f64, i32, f64(math.minInt(i32))+1, math.minInt(i32)+1);
86 test__fixint(f64, i32, -2.0, -2);
87 test__fixint(f64, i32, -1.9, -1);
88 test__fixint(f64, i32, -1.1, -1);
89 test__fixint(f64, i32, -1.0, -1);
90 test__fixint(f64, i32, -0.9, 0);
91 test__fixint(f64, i32, -0.1, 0);
92 test__fixint(f64, i32, -math.f32_min, 0);
93 test__fixint(f64, i32, -0.0, 0);
94 test__fixint(f64, i32, 0.0, 0);
95 test__fixint(f64, i32, math.f32_min, 0);
96 test__fixint(f64, i32, 0.1, 0);
97 test__fixint(f64, i32, 0.9, 0);
98 test__fixint(f64, i32, 1.0, 1);
99 test__fixint(f64, i32, f64(math.maxInt(i32))-1, math.maxInt(i32)-1);
100 test__fixint(f64, i32, f64(math.maxInt(i32)), math.maxInt(i32));
101 test__fixint(f64, i32, math.f64_max, math.maxInt(i32));
102 test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));
103}
104
105test "fixint.i64" {
106 test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));
107 test__fixint(f64, i64, -math.f64_max, math.minInt(i64));
108 test__fixint(f64, i64, f64(math.minInt(i64)), math.minInt(i64));
109 test__fixint(f64, i64, f64(math.minInt(i64))+1, math.minInt(i64));
110 test__fixint(f64, i64, f64(math.minInt(i64)/2), math.minInt(i64)/2);
111 test__fixint(f64, i64, -2.0, -2);
112 test__fixint(f64, i64, -1.9, -1);
113 test__fixint(f64, i64, -1.1, -1);
114 test__fixint(f64, i64, -1.0, -1);
115 test__fixint(f64, i64, -0.9, 0);
116 test__fixint(f64, i64, -0.1, 0);
117 test__fixint(f64, i64, -math.f32_min, 0);
118 test__fixint(f64, i64, -0.0, 0);
119 test__fixint(f64, i64, 0.0, 0);
120 test__fixint(f64, i64, math.f32_min, 0);
121 test__fixint(f64, i64, 0.1, 0);
122 test__fixint(f64, i64, 0.9, 0);
123 test__fixint(f64, i64, 1.0, 1);
124 test__fixint(f64, i64, f64(math.maxInt(i64))-1, math.maxInt(i64));
125 test__fixint(f64, i64, f64(math.maxInt(i64)), math.maxInt(i64));
126 test__fixint(f64, i64, math.f64_max, math.maxInt(i64));
127 test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));
128}
129
130test "fixint.i128" {
131 test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));
132 test__fixint(f64, i128, -math.f64_max, math.minInt(i128));
133 test__fixint(f64, i128, f64(math.minInt(i128)), math.minInt(i128));
134 test__fixint(f64, i128, f64(math.minInt(i128))+1, math.minInt(i128));
135 test__fixint(f64, i128, -2.0, -2);
136 test__fixint(f64, i128, -1.9, -1);
137 test__fixint(f64, i128, -1.1, -1);
138 test__fixint(f64, i128, -1.0, -1);
139 test__fixint(f64, i128, -0.9, 0);
140 test__fixint(f64, i128, -0.1, 0);
141 test__fixint(f64, i128, -math.f32_min, 0);
142 test__fixint(f64, i128, -0.0, 0);
143 test__fixint(f64, i128, 0.0, 0);
144 test__fixint(f64, i128, math.f32_min, 0);
145 test__fixint(f64, i128, 0.1, 0);
146 test__fixint(f64, i128, 0.9, 0);
147 test__fixint(f64, i128, 1.0, 1);
148 test__fixint(f64, i128, f64(math.maxInt(i128))-1, math.maxInt(i128));
149 test__fixint(f64, i128, f64(math.maxInt(i128)), math.maxInt(i128));
150 test__fixint(f64, i128, math.f64_max, math.maxInt(i128));
151 test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));
152}
std/special/compiler_rt/fixsfdi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixsfdi(a: f32) i64 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f32, i64, a);
7}
8
9test "import fixsfdi" {
10 _ = @import("fixsfdi_test.zig");
11}
std/special/compiler_rt/fixsfdi_test.zig created+68
......@@ -0,0 +1,68 @@
1const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixsfdi(a: f32, expected: i64) void {
8 const x = __fixsfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
10 assert(x == expected);
11}
12
13test "fixsfdi" {
14 //warn("\n");
15
16 test__fixsfdi(-math.f32_max, math.minInt(i64));
17
18 test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
19 test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
20
21 test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000);
22 test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
23 test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
24
25 test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000);
26 test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000);
27 test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
28 test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
29
30 test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000);
31 test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
32 test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
33
34 test__fixsfdi(-2.01, -2);
35 test__fixsfdi(-2.0, -2);
36 test__fixsfdi(-1.99, -1);
37 test__fixsfdi(-1.0, -1);
38 test__fixsfdi(-0.99, 0);
39 test__fixsfdi(-0.5, 0);
40 test__fixsfdi(-math.f32_min, 0);
41 test__fixsfdi(0.0, 0);
42 test__fixsfdi(math.f32_min, 0);
43 test__fixsfdi(0.5, 0);
44 test__fixsfdi(0.99, 0);
45 test__fixsfdi(1.0, 1);
46 test__fixsfdi(1.5, 1);
47 test__fixsfdi(1.99, 1);
48 test__fixsfdi(2.0, 2);
49 test__fixsfdi(2.01, 2);
50
51 test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
52 test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
53 test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
54
55 test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
56 test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
57 test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
58 test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
59
60 test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
61 test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
62 test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
63
64 test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
65 test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
66
67 test__fixsfdi(math.f64_max, math.maxInt(i64));
68}
std/special/compiler_rt/fixsfsi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixsfsi(a: f32) i32 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f32, i32, a);
7}
8
9test "import fixsfsi" {
10 _ = @import("fixsfsi_test.zig");
11}
std/special/compiler_rt/fixsfsi_test.zig created+76
......@@ -0,0 +1,76 @@
1const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixsfsi(a: f32, expected: i32) void {
8 const x = __fixsfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
10 assert(x == expected);
11}
12
13test "fixsfsi" {
14 //warn("\n");
15
16 test__fixsfsi(-math.f32_max, math.minInt(i32));
17
18 test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
19 test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
20
21 test__fixsfsi(-0x1.0000000000000p+127, -0x80000000);
22 test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
23 test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
24
25 test__fixsfsi(-0x1.0000000000001p+63, -0x80000000);
26 test__fixsfsi(-0x1.0000000000000p+63, -0x80000000);
27 test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
28 test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
29
30 test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000);
31 test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000);
32
33 test__fixsfsi(-0x1.000000p+31, -0x80000000);
34 test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000);
35 test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
36 test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
37
38 test__fixsfsi(-2.01, -2);
39 test__fixsfsi(-2.0, -2);
40 test__fixsfsi(-1.99, -1);
41 test__fixsfsi(-1.0, -1);
42 test__fixsfsi(-0.99, 0);
43 test__fixsfsi(-0.5, 0);
44 test__fixsfsi(-math.f32_min, 0);
45 test__fixsfsi(0.0, 0);
46 test__fixsfsi(math.f32_min, 0);
47 test__fixsfsi(0.5, 0);
48 test__fixsfsi(0.99, 0);
49 test__fixsfsi(1.0, 1);
50 test__fixsfsi(1.5, 1);
51 test__fixsfsi(1.99, 1);
52 test__fixsfsi(2.0, 2);
53 test__fixsfsi(2.01, 2);
54
55 test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
56 test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
57 test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF);
58 test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF);
59
60 test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
61 test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
62
63 test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
64 test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
65 test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
66 test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
67
68 test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
69 test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
70 test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
71
72 test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
73 test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
74
75 test__fixsfsi(math.f32_max, math.maxInt(i32));
76}
std/special/compiler_rt/fixsfti.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixsfti(a: f32) i128 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f32, i128, a);
7}
8
9test "import fixsfti" {
10 _ = @import("fixsfti_test.zig");
11}
std/special/compiler_rt/fixsfti_test.zig created+84
......@@ -0,0 +1,84 @@
1const __fixsfti = @import("fixsfti.zig").__fixsfti;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixsfti(a: f32, expected: i128) void {
8 const x = __fixsfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
10 assert(x == expected);
11}
12
13test "fixsfti" {
14 //warn("\n");
15
16 test__fixsfti(-math.f32_max, math.minInt(i128));
17
18 test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
19 test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
20
21 test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
22 test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
23 test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
24 test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
25 test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
26 test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
27
28 test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000);
29 test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000);
30 test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
31 test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
32
33 test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000);
34 test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
35 test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
36
37 test__fixsfti(-0x1.000000p+31, -0x80000000);
38 test__fixsfti(-0x1.FFFFFFp+30, -0x80000000);
39 test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80);
40 test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00);
41
42 test__fixsfti(-2.01, -2);
43 test__fixsfti(-2.0, -2);
44 test__fixsfti(-1.99, -1);
45 test__fixsfti(-1.0, -1);
46 test__fixsfti(-0.99, 0);
47 test__fixsfti(-0.5, 0);
48 test__fixsfti(-math.f32_min, 0);
49 test__fixsfti(0.0, 0);
50 test__fixsfti(math.f32_min, 0);
51 test__fixsfti(0.5, 0);
52 test__fixsfti(0.99, 0);
53 test__fixsfti(1.0, 1);
54 test__fixsfti(1.5, 1);
55 test__fixsfti(1.99, 1);
56 test__fixsfti(2.0, 2);
57 test__fixsfti(2.01, 2);
58
59 test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00);
60 test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80);
61 test__fixsfti(0x1.FFFFFFp+30, 0x80000000);
62 test__fixsfti(0x1.000000p+31, 0x80000000);
63
64 test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
65 test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
66 test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000);
67
68 test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
69 test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
70 test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000);
71 test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000);
72
73 test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
74 test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
75 test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
76 test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
77 test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
78 test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
79
80 test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
81 test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
82
83 test__fixsfti(math.f32_max, math.maxInt(i128));
84}
std/special/compiler_rt/fixtfdi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixtfdi(a: f128) i64 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f128, i64, a);
7}
8
9test "import fixtfdi" {
10 _ = @import("fixtfdi_test.zig");
11}
std/special/compiler_rt/fixtfdi_test.zig created+76
......@@ -0,0 +1,76 @@
1const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixtfdi(a: f128, expected: i64) void {
8 const x = __fixtfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
10 assert(x == expected);
11}
12
13test "fixtfdi" {
14 //warn("\n");
15
16 test__fixtfdi(-math.f128_max, math.minInt(i64));
17
18 test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
19 test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
20
21 test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000);
22 test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
23 test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
24
25 test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000);
26 test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000);
27 test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
28 test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
29
30 test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
31 test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
32
33 test__fixtfdi(-0x1.000000p+31, -0x80000000);
34 test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
35 test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80);
36 test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00);
37
38 test__fixtfdi(-2.01, -2);
39 test__fixtfdi(-2.0, -2);
40 test__fixtfdi(-1.99, -1);
41 test__fixtfdi(-1.0, -1);
42 test__fixtfdi(-0.99, 0);
43 test__fixtfdi(-0.5, 0);
44 test__fixtfdi(-math.f64_min, 0);
45 test__fixtfdi(0.0, 0);
46 test__fixtfdi(math.f64_min, 0);
47 test__fixtfdi(0.5, 0);
48 test__fixtfdi(0.99, 0);
49 test__fixtfdi(1.0, 1);
50 test__fixtfdi(1.5, 1);
51 test__fixtfdi(1.99, 1);
52 test__fixtfdi(2.0, 2);
53 test__fixtfdi(2.01, 2);
54
55 test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00);
56 test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80);
57 test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0);
58 test__fixtfdi(0x1.000000p+31, 0x80000000);
59
60 test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
61 test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
62
63 test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
64 test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
65 test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
66 test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
67
68 test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
69 test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
70 test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
71
72 test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
73 test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
74
75 test__fixtfdi(math.f128_max, math.maxInt(i64));
76}
std/special/compiler_rt/fixtfsi.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixtfsi(a: f128) i32 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f128, i32, a);
7}
8
9test "import fixtfsi" {
10 _ = @import("fixtfsi_test.zig");
11}
std/special/compiler_rt/fixtfsi_test.zig created+76
......@@ -0,0 +1,76 @@
1const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixtfsi(a: f128, expected: i32) void {
8 const x = __fixtfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
10 assert(x == expected);
11}
12
13test "fixtfsi" {
14 //warn("\n");
15
16 test__fixtfsi(-math.f128_max, math.minInt(i32));
17
18 test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
19 test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
20
21 test__fixtfsi(-0x1.0000000000000p+127, -0x80000000);
22 test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
23 test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
24
25 test__fixtfsi(-0x1.0000000000001p+63, -0x80000000);
26 test__fixtfsi(-0x1.0000000000000p+63, -0x80000000);
27 test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
28 test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
29
30 test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000);
31 test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000);
32
33 test__fixtfsi(-0x1.000000p+31, -0x80000000);
34 test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
35 test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
36 test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
37
38 test__fixtfsi(-2.01, -2);
39 test__fixtfsi(-2.0, -2);
40 test__fixtfsi(-1.99, -1);
41 test__fixtfsi(-1.0, -1);
42 test__fixtfsi(-0.99, 0);
43 test__fixtfsi(-0.5, 0);
44 test__fixtfsi(-math.f32_min, 0);
45 test__fixtfsi(0.0, 0);
46 test__fixtfsi(math.f32_min, 0);
47 test__fixtfsi(0.5, 0);
48 test__fixtfsi(0.99, 0);
49 test__fixtfsi(1.0, 1);
50 test__fixtfsi(1.5, 1);
51 test__fixtfsi(1.99, 1);
52 test__fixtfsi(2.0, 2);
53 test__fixtfsi(2.01, 2);
54
55 test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
56 test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
57 test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
58 test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF);
59
60 test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
61 test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
62
63 test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
64 test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
65 test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
66 test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
67
68 test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
69 test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
70 test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
71
72 test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
73 test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
74
75 test__fixtfsi(math.f128_max, math.maxInt(i32));
76}
std/special/compiler_rt/fixtfti.zig created+11
......@@ -0,0 +1,11 @@
1const fixint = @import("fixint.zig").fixint;
2const builtin = @import("builtin");
3
4pub extern fn __fixtfti(a: f128) i128 {
5 @setRuntimeSafety(builtin.is_test);
6 return fixint(f128, i128, a);
7}
8
9test "import fixtfti" {
10 _ = @import("fixtfti_test.zig");
11}
std/special/compiler_rt/fixtfti_test.zig created+66
......@@ -0,0 +1,66 @@
1const __fixtfti = @import("fixtfti.zig").__fixtfti;
2const std = @import("std");
3const math = std.math;
4const assert = std.debug.assert;
5const warn = std.debug.warn;
6
7fn test__fixtfti(a: f128, expected: i128) void {
8 const x = __fixtfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
10 assert(x == expected);
11}
12
13test "fixtfti" {
14 //warn("\n");
15
16 test__fixtfti(-math.f128_max, math.minInt(i128));
17
18 test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
19 test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
20
21 test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
22 test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
23 test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
24
25 test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800);
26 test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000);
27 test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
28 test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
29
30 test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
31 test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
32
33 test__fixtfti(-2.01, -2);
34 test__fixtfti(-2.0, -2);
35 test__fixtfti(-1.99, -1);
36 test__fixtfti(-1.0, -1);
37 test__fixtfti(-0.99, 0);
38 test__fixtfti(-0.5, 0);
39 test__fixtfti(-math.f128_min, 0);
40 test__fixtfti(0.0, 0);
41 test__fixtfti(math.f128_min, 0);
42 test__fixtfti(0.5, 0);
43 test__fixtfti(0.99, 0);
44 test__fixtfti(1.0, 1);
45 test__fixtfti(1.5, 1);
46 test__fixtfti(1.99, 1);
47 test__fixtfti(2.0, 2);
48 test__fixtfti(2.01, 2);
49
50 test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
51 test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
52
53 test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
54 test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
55 test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000);
56 test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800);
57
58 test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
59 test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
60 test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
61
62 test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
63 test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
64
65 test__fixtfti(math.f128_max, math.maxInt(i128));
66}
std/special/compiler_rt/index.zig+90-63
......@@ -52,6 +52,16 @@ comptime {
5252 @export("__fixunstfdi", @import("fixunstfdi.zig").__fixunstfdi, linkage);
5353 @export("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage);
5454
55 @export("__fixdfdi", @import("fixdfdi.zig").__fixdfdi, linkage);
56 @export("__fixdfsi", @import("fixdfsi.zig").__fixdfsi, linkage);
57 @export("__fixdfti", @import("fixdfti.zig").__fixdfti, linkage);
58 @export("__fixsfdi", @import("fixsfdi.zig").__fixsfdi, linkage);
59 @export("__fixsfsi", @import("fixsfsi.zig").__fixsfsi, linkage);
60 @export("__fixsfti", @import("fixsfti.zig").__fixsfti, linkage);
61 @export("__fixtfdi", @import("fixtfdi.zig").__fixtfdi, linkage);
62 @export("__fixtfsi", @import("fixtfsi.zig").__fixtfsi, linkage);
63 @export("__fixtfti", @import("fixtfti.zig").__fixtfti, linkage);
64
5565 @export("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage);
5666
5767 @export("__udivsi3", __udivsi3, linkage);
......@@ -59,7 +69,7 @@ comptime {
5969 @export("__umoddi3", __umoddi3, linkage);
6070 @export("__udivmodsi4", __udivmodsi4, linkage);
6171
62 if (isArmArch()) {
72 if (is_arm_arch and !is_arm_64) {
6373 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
6474 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
6575 @export("__aeabi_uidiv", __udivsi3, linkage);
......@@ -149,68 +159,85 @@ extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult
149159 return result;
150160}
151161
152fn isArmArch() bool {
153 return switch (builtin.arch) {
154 builtin.Arch.armv8_3a,
155 builtin.Arch.armv8_2a,
156 builtin.Arch.armv8_1a,
157 builtin.Arch.armv8,
158 builtin.Arch.armv8r,
159 builtin.Arch.armv8m_baseline,
160 builtin.Arch.armv8m_mainline,
161 builtin.Arch.armv7,
162 builtin.Arch.armv7em,
163 builtin.Arch.armv7m,
164 builtin.Arch.armv7s,
165 builtin.Arch.armv7k,
166 builtin.Arch.armv7ve,
167 builtin.Arch.armv6,
168 builtin.Arch.armv6m,
169 builtin.Arch.armv6k,
170 builtin.Arch.armv6t2,
171 builtin.Arch.armv5,
172 builtin.Arch.armv5te,
173 builtin.Arch.armv4t,
174 builtin.Arch.armebv8_3a,
175 builtin.Arch.armebv8_2a,
176 builtin.Arch.armebv8_1a,
177 builtin.Arch.armebv8,
178 builtin.Arch.armebv8r,
179 builtin.Arch.armebv8m_baseline,
180 builtin.Arch.armebv8m_mainline,
181 builtin.Arch.armebv7,
182 builtin.Arch.armebv7em,
183 builtin.Arch.armebv7m,
184 builtin.Arch.armebv7s,
185 builtin.Arch.armebv7k,
186 builtin.Arch.armebv7ve,
187 builtin.Arch.armebv6,
188 builtin.Arch.armebv6m,
189 builtin.Arch.armebv6k,
190 builtin.Arch.armebv6t2,
191 builtin.Arch.armebv5,
192 builtin.Arch.armebv5te,
193 builtin.Arch.armebv4t,
194 builtin.Arch.aarch64v8_3a,
195 builtin.Arch.aarch64v8_2a,
196 builtin.Arch.aarch64v8_1a,
197 builtin.Arch.aarch64v8,
198 builtin.Arch.aarch64v8r,
199 builtin.Arch.aarch64v8m_baseline,
200 builtin.Arch.aarch64v8m_mainline,
201 builtin.Arch.aarch64_bev8_3a,
202 builtin.Arch.aarch64_bev8_2a,
203 builtin.Arch.aarch64_bev8_1a,
204 builtin.Arch.aarch64_bev8,
205 builtin.Arch.aarch64_bev8r,
206 builtin.Arch.aarch64_bev8m_baseline,
207 builtin.Arch.aarch64_bev8m_mainline,
208 builtin.Arch.thumb,
209 builtin.Arch.thumbeb,
210 => true,
211 else => false,
212 };
213}
162const is_arm_64 = switch (builtin.arch) {
163 builtin.Arch.aarch64v8_3a,
164 builtin.Arch.aarch64v8_2a,
165 builtin.Arch.aarch64v8_1a,
166 builtin.Arch.aarch64v8,
167 builtin.Arch.aarch64v8r,
168 builtin.Arch.aarch64v8m_baseline,
169 builtin.Arch.aarch64v8m_mainline,
170 builtin.Arch.aarch64_bev8_3a,
171 builtin.Arch.aarch64_bev8_2a,
172 builtin.Arch.aarch64_bev8_1a,
173 builtin.Arch.aarch64_bev8,
174 builtin.Arch.aarch64_bev8r,
175 builtin.Arch.aarch64_bev8m_baseline,
176 builtin.Arch.aarch64_bev8m_mainline,
177 => true,
178 else => false,
179};
180
181const is_arm_arch = switch (builtin.arch) {
182 builtin.Arch.armv8_3a,
183 builtin.Arch.armv8_2a,
184 builtin.Arch.armv8_1a,
185 builtin.Arch.armv8,
186 builtin.Arch.armv8r,
187 builtin.Arch.armv8m_baseline,
188 builtin.Arch.armv8m_mainline,
189 builtin.Arch.armv7,
190 builtin.Arch.armv7em,
191 builtin.Arch.armv7m,
192 builtin.Arch.armv7s,
193 builtin.Arch.armv7k,
194 builtin.Arch.armv7ve,
195 builtin.Arch.armv6,
196 builtin.Arch.armv6m,
197 builtin.Arch.armv6k,
198 builtin.Arch.armv6t2,
199 builtin.Arch.armv5,
200 builtin.Arch.armv5te,
201 builtin.Arch.armv4t,
202 builtin.Arch.armebv8_3a,
203 builtin.Arch.armebv8_2a,
204 builtin.Arch.armebv8_1a,
205 builtin.Arch.armebv8,
206 builtin.Arch.armebv8r,
207 builtin.Arch.armebv8m_baseline,
208 builtin.Arch.armebv8m_mainline,
209 builtin.Arch.armebv7,
210 builtin.Arch.armebv7em,
211 builtin.Arch.armebv7m,
212 builtin.Arch.armebv7s,
213 builtin.Arch.armebv7k,
214 builtin.Arch.armebv7ve,
215 builtin.Arch.armebv6,
216 builtin.Arch.armebv6m,
217 builtin.Arch.armebv6k,
218 builtin.Arch.armebv6t2,
219 builtin.Arch.armebv5,
220 builtin.Arch.armebv5te,
221 builtin.Arch.armebv4t,
222 builtin.Arch.aarch64v8_3a,
223 builtin.Arch.aarch64v8_2a,
224 builtin.Arch.aarch64v8_1a,
225 builtin.Arch.aarch64v8,
226 builtin.Arch.aarch64v8r,
227 builtin.Arch.aarch64v8m_baseline,
228 builtin.Arch.aarch64v8m_mainline,
229 builtin.Arch.aarch64_bev8_3a,
230 builtin.Arch.aarch64_bev8_2a,
231 builtin.Arch.aarch64_bev8_1a,
232 builtin.Arch.aarch64_bev8,
233 builtin.Arch.aarch64_bev8r,
234 builtin.Arch.aarch64_bev8m_baseline,
235 builtin.Arch.aarch64_bev8m_mainline,
236 builtin.Arch.thumb,
237 builtin.Arch.thumbeb,
238 => true,
239 else => false,
240};
214241
215242nakedcc fn __aeabi_uidivmod() void {
216243 @setRuntimeSafety(false);
std/unicode.zig+16-16
......@@ -208,7 +208,7 @@ pub const Utf8View = struct {
208208 }
209209};
210210
211const Utf8Iterator = struct {
211pub const Utf8Iterator = struct {
212212 bytes: []const u8,
213213 i: usize,
214214
......@@ -249,12 +249,12 @@ pub const Utf16LeIterator = struct {
249249 pub fn nextCodepoint(it: *Utf16LeIterator) !?u32 {
250250 assert(it.i <= it.bytes.len);
251251 if (it.i == it.bytes.len) return null;
252 const c0: u32 = mem.readIntLE(u16, it.bytes[it.i .. it.i + 2]);
252 const c0: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
253253 if (c0 & ~u32(0x03ff) == 0xd800) {
254254 // surrogate pair
255255 it.i += 2;
256256 if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf;
257 const c1: u32 = mem.readIntLE(u16, it.bytes[it.i .. it.i + 2]);
257 const c1: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
258258 if (c1 & ~u32(0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf;
259259 it.i += 2;
260260 return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff));
......@@ -510,46 +510,46 @@ test "utf16leToUtf8" {
510510 const utf16le_as_bytes = @sliceToBytes(utf16le[0..]);
511511
512512 {
513 mem.writeInt(utf16le_as_bytes[0..], u16('A'), builtin.Endian.Little);
514 mem.writeInt(utf16le_as_bytes[2..], u16('a'), builtin.Endian.Little);
513 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
514 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a');
515515 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
516516 assert(mem.eql(u8, utf8, "Aa"));
517517 }
518518
519519 {
520 mem.writeInt(utf16le_as_bytes[0..], u16(0x80), builtin.Endian.Little);
521 mem.writeInt(utf16le_as_bytes[2..], u16(0xffff), builtin.Endian.Little);
520 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80);
521 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff);
522522 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
523523 assert(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf"));
524524 }
525525
526526 {
527527 // the values just outside the surrogate half range
528 mem.writeInt(utf16le_as_bytes[0..], u16(0xd7ff), builtin.Endian.Little);
529 mem.writeInt(utf16le_as_bytes[2..], u16(0xe000), builtin.Endian.Little);
528 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff);
529 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000);
530530 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
531531 assert(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80"));
532532 }
533533
534534 {
535535 // smallest surrogate pair
536 mem.writeInt(utf16le_as_bytes[0..], u16(0xd800), builtin.Endian.Little);
537 mem.writeInt(utf16le_as_bytes[2..], u16(0xdc00), builtin.Endian.Little);
536 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800);
537 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
538538 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
539539 assert(mem.eql(u8, utf8, "\xf0\x90\x80\x80"));
540540 }
541541
542542 {
543543 // largest surrogate pair
544 mem.writeInt(utf16le_as_bytes[0..], u16(0xdbff), builtin.Endian.Little);
545 mem.writeInt(utf16le_as_bytes[2..], u16(0xdfff), builtin.Endian.Little);
544 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
545 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff);
546546 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
547547 assert(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf"));
548548 }
549549
550550 {
551 mem.writeInt(utf16le_as_bytes[0..], u16(0xdbff), builtin.Endian.Little);
552 mem.writeInt(utf16le_as_bytes[2..], u16(0xdc00), builtin.Endian.Little);
551 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
552 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
553553 const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
554554 assert(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80"));
555555 }
......@@ -583,7 +583,7 @@ pub fn utf8ToUtf16Le(utf16le: []u16, utf8: []const u8) !usize {
583583 while (it.nextCodepoint()) |codepoint| {
584584 if (end_index == utf16le_as_bytes.len) return (end_index / 2) + 1;
585585 // TODO surrogate pairs
586 mem.writeInt(utf16le_as_bytes[end_index..], @intCast(u16, codepoint), builtin.Endian.Little);
586 mem.writeIntSliceLittle(u16, utf16le_as_bytes[end_index..], @intCast(u16, codepoint));
587587 end_index += 2;
588588 }
589589 return end_index / 2;
test/behavior.zig+4
......@@ -8,6 +8,7 @@ comptime {
88 _ = @import("cases/atomics.zig");
99 _ = @import("cases/bitcast.zig");
1010 _ = @import("cases/bool.zig");
11 _ = @import("cases/bswap.zig");
1112 _ = @import("cases/bugs/1076.zig");
1213 _ = @import("cases/bugs/1111.zig");
1314 _ = @import("cases/bugs/1277.zig");
......@@ -41,6 +42,7 @@ comptime {
4142 _ = @import("cases/if.zig");
4243 _ = @import("cases/import.zig");
4344 _ = @import("cases/incomplete_struct_param_tld.zig");
45 _ = @import("cases/inttoptr.zig");
4446 _ = @import("cases/ir_block_deps.zig");
4547 _ = @import("cases/math.zig");
4648 _ = @import("cases/merge_error_sets.zig");
......@@ -51,6 +53,7 @@ comptime {
5153 _ = @import("cases/optional.zig");
5254 _ = @import("cases/pointers.zig");
5355 _ = @import("cases/popcount.zig");
56 _ = @import("cases/ptrcast.zig");
5457 _ = @import("cases/pub_enum/index.zig");
5558 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
5659 _ = @import("cases/reflection.zig");
......@@ -64,6 +67,7 @@ comptime {
6467 _ = @import("cases/switch_prong_implicit_cast.zig");
6568 _ = @import("cases/syntax.zig");
6669 _ = @import("cases/this.zig");
70 _ = @import("cases/truncate.zig");
6771 _ = @import("cases/try.zig");
6872 _ = @import("cases/type_info.zig");
6973 _ = @import("cases/undefined.zig");
test/cases/asm.zig+24
......@@ -17,6 +17,30 @@ test "module level assembly" {
1717 }
1818}
1919
20test "output constraint modifiers" {
21 // This is only testing compilation.
22 var a: u32 = 3;
23 asm volatile ("" : [_]"=m,r"(a) : : "");
24 asm volatile ("" : [_]"=r,m"(a) : : "");
25}
26
27test "alternative constraints" {
28 // Make sure we allow commas as a separator for alternative constraints.
29 var a: u32 = 3;
30 asm volatile ("" : [_]"=r,m"(a) : [_]"r,m"(a) : "");
31}
32
33test "sized integer/float in asm input" {
34 asm volatile ("" : : [_]"m"(usize(3)) : "");
35 asm volatile ("" : : [_]"m"(i15(-3)) : "");
36 asm volatile ("" : : [_]"m"(u3(3)) : "");
37 asm volatile ("" : : [_]"m"(i3(3)) : "");
38 asm volatile ("" : : [_]"m"(u121(3)) : "");
39 asm volatile ("" : : [_]"m"(i121(3)) : "");
40 asm volatile ("" : : [_]"m"(f32(3.17)) : "");
41 asm volatile ("" : : [_]"m"(f64(3.17)) : "");
42}
43
2044extern fn aoeu() i32;
2145
2246export fn derp() i32 {
test/cases/bswap.zig created+32
......@@ -0,0 +1,32 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4test "@bswap" {
5 comptime testByteSwap();
6 testByteSwap();
7}
8
9fn testByteSwap() void {
10 assert(@bswap(u0, 0) == 0);
11 assert(@bswap(u8, 0x12) == 0x12);
12 assert(@bswap(u16, 0x1234) == 0x3412);
13 assert(@bswap(u24, 0x123456) == 0x563412);
14 assert(@bswap(u32, 0x12345678) == 0x78563412);
15 assert(@bswap(u40, 0x123456789a) == 0x9a78563412);
16 assert(@bswap(u48, 0x123456789abc) == 0xbc9a78563412);
17 assert(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412);
18 assert(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412);
19 assert(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412);
20
21 assert(@bswap(i0, 0) == 0);
22 assert(@bswap(i8, -50) == -50);
23 assert(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412)));
24 assert(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412)));
25 assert(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412)));
26 assert(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412)));
27 assert(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412)));
28 assert(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412)));
29 assert(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412)));
30 assert(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) ==
31 @bitCast(i128, u128(0x8171615141312111f1debc9a78563412)));
32}
test/cases/cast.zig+18
......@@ -452,3 +452,21 @@ test "implicit ptr to *c_void" {
452452 var c: *u32 = @ptrCast(*u32, ptr2.?);
453453 assert(c.* == 1);
454454}
455
456test "@intCast to comptime_int" {
457 assert(@intCast(comptime_int, 0) == 0);
458}
459
460test "implicit cast comptime numbers to any type when the value fits" {
461 const a: u64 = 255;
462 var b: u8 = a;
463 assert(b == 255);
464}
465
466test "@intToEnum passed a comptime_int to an enum with one item" {
467 const E = enum {
468 A,
469 };
470 const x = @intToEnum(E, 0);
471 assert(x == E.A);
472}
test/cases/inttoptr.zig created+13
......@@ -0,0 +1,13 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const assertOrPanic = std.debug.assertOrPanic;
4
5test "casting random address to function pointer" {
6 randomAddressToFunction();
7 comptime randomAddressToFunction();
8}
9
10fn randomAddressToFunction() void {
11 var addr: usize = 0xdeadbeef;
12 var ptr = @intToPtr(fn () void, addr);
13}
test/cases/ptrcast.zig created+36
......@@ -0,0 +1,36 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const assertOrPanic = std.debug.assertOrPanic;
4
5test "reinterpret bytes as integer with nonzero offset" {
6 testReinterpretBytesAsInteger();
7 comptime testReinterpretBytesAsInteger();
8}
9
10fn testReinterpretBytesAsInteger() void {
11 const bytes = "\x12\x34\x56\x78\xab";
12 const expected = switch (builtin.endian) {
13 builtin.Endian.Little => 0xab785634,
14 builtin.Endian.Big => 0x345678ab,
15 };
16 assertOrPanic(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);
17}
18
19test "reinterpret bytes of an array into an extern struct" {
20 testReinterpretBytesAsExternStruct();
21 comptime testReinterpretBytesAsExternStruct();
22}
23
24fn testReinterpretBytesAsExternStruct() void {
25 var bytes align(2) = []u8{ 1, 2, 3, 4, 5, 6 };
26
27 const S = extern struct {
28 a: u8,
29 b: u16,
30 c: u8,
31 };
32
33 var ptr = @ptrCast(*const S, &bytes);
34 var val = ptr.c;
35 assertOrPanic(val == 5);
36}
test/cases/struct_contains_slice_of_itself.zig+42
......@@ -5,6 +5,11 @@ const Node = struct {
55 children: []Node,
66};
77
8const NodeAligned = struct {
9 payload: i32,
10 children: []align(@alignOf(NodeAligned)) NodeAligned,
11};
12
813test "struct contains slice of itself" {
914 var other_nodes = []Node{
1015 Node{
......@@ -41,3 +46,40 @@ test "struct contains slice of itself" {
4146 assert(root.children[2].children[0].payload == 31);
4247 assert(root.children[2].children[1].payload == 32);
4348}
49
50test "struct contains aligned slice of itself" {
51 var other_nodes = []NodeAligned{
52 NodeAligned{
53 .payload = 31,
54 .children = []NodeAligned{},
55 },
56 NodeAligned{
57 .payload = 32,
58 .children = []NodeAligned{},
59 },
60 };
61 var nodes = []NodeAligned{
62 NodeAligned{
63 .payload = 1,
64 .children = []NodeAligned{},
65 },
66 NodeAligned{
67 .payload = 2,
68 .children = []NodeAligned{},
69 },
70 NodeAligned{
71 .payload = 3,
72 .children = other_nodes[0..],
73 },
74 };
75 const root = NodeAligned{
76 .payload = 1234,
77 .children = nodes[0..],
78 };
79 assert(root.payload == 1234);
80 assert(root.children[0].payload == 1);
81 assert(root.children[1].payload == 2);
82 assert(root.children[2].payload == 3);
83 assert(root.children[2].children[0].payload == 31);
84 assert(root.children[2].children[1].payload == 32);
85}
test/cases/truncate.zig created+8
......@@ -0,0 +1,8 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4test "truncate u0 to larger integer allowed and has comptime known result" {
5 var x: u0 = 0;
6 const y = @truncate(u8, x);
7 comptime assert(y == 0);
8}
test/compile_errors.zig+109-31
......@@ -1,6 +1,85 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "reading past end of pointer casted array",
6 \\comptime {
7 \\ const array = "aoeu";
8 \\ const slice = array[2..];
9 \\ const int_ptr = @ptrCast(*const u24, slice.ptr);
10 \\ const deref = int_ptr.*;
11 \\}
12 ,
13 ".tmp_source.zig:5:26: error: attempt to read 3 bytes from [4]u8 at index 2 which is 2 bytes",
14 );
15
16 cases.add(
17 "error note for function parameter incompatibility",
18 \\fn do_the_thing(func: fn (arg: i32) void) void {}
19 \\fn bar(arg: bool) void {}
20 \\export fn entry() void {
21 \\ do_the_thing(bar);
22 \\}
23 ,
24 ".tmp_source.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void",
25 ".tmp_source.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'",
26 );
27
28 cases.add(
29 "cast negative value to unsigned integer",
30 \\comptime {
31 \\ const value: i32 = -1;
32 \\ const unsigned = @intCast(u32, value);
33 \\}
34 \\export fn entry1() void {
35 \\ const value: i32 = -1;
36 \\ const unsigned: u32 = value;
37 \\}
38 ,
39 ".tmp_source.zig:3:36: error: cannot cast negative value -1 to unsigned integer type 'u32'",
40 ".tmp_source.zig:7:27: error: cannot cast negative value -1 to unsigned integer type 'u32'",
41 );
42
43 cases.add(
44 "integer cast truncates bits",
45 \\export fn entry1() void {
46 \\ const spartan_count: u16 = 300;
47 \\ const byte = @intCast(u8, spartan_count);
48 \\}
49 \\export fn entry2() void {
50 \\ const spartan_count: u16 = 300;
51 \\ const byte: u8 = spartan_count;
52 \\}
53 \\export fn entry3() void {
54 \\ var spartan_count: u16 = 300;
55 \\ var byte: u8 = spartan_count;
56 \\}
57 ,
58 ".tmp_source.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'",
59 ".tmp_source.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'",
60 ".tmp_source.zig:11:20: error: expected type 'u8', found 'u16'",
61 );
62
63 cases.add(
64 "comptime implicit cast f64 to f32",
65 \\export fn entry() void {
66 \\ const x: f64 = 16777217;
67 \\ const y: f32 = x;
68 \\}
69 ,
70 ".tmp_source.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information",
71 );
72
73 cases.add(
74 "implicit cast from f64 to f32",
75 \\var x: f64 = 1.0;
76 \\var y: f32 = x;
77 \\
78 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
79 ,
80 ".tmp_source.zig:2:14: error: expected type 'f32', found 'f64'",
81 );
82
483 cases.add(
584 "exceeded maximum bit width of integer",
685 \\export fn entry1() void {
......@@ -1819,7 +1898,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18191898 \\ if (0) {}
18201899 \\}
18211900 ,
1822 ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'",
1901 ".tmp_source.zig:2:9: error: expected type 'bool', found 'comptime_int'",
18231902 );
18241903
18251904 cases.add(
......@@ -2422,16 +2501,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
24222501 ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'",
24232502 );
24242503
2425 cases.add(
2426 "implicit cast from f64 to f32",
2427 \\const x : f64 = 1.0;
2428 \\const y : f32 = x;
2429 \\
2430 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
2431 ,
2432 ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'",
2433 );
2434
24352504 cases.add(
24362505 "colliding invalid top level functions",
24372506 \\fn func() bogus {}
......@@ -3174,6 +3243,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
31743243 \\fn something() anyerror!void { }
31753244 ,
31763245 ".tmp_source.zig:2:5: error: expected type 'void', found 'anyerror'",
3246 ".tmp_source.zig:1:15: note: return type declared here",
31773247 );
31783248
31793249 cases.add(
......@@ -4049,16 +4119,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40494119 ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",
40504120 );
40514121
4052 cases.add(
4053 "cast negative value to unsigned integer",
4054 \\comptime {
4055 \\ const value: i32 = -1;
4056 \\ const unsigned = @intCast(u32, value);
4057 \\}
4058 ,
4059 ".tmp_source.zig:3:22: error: attempt to cast negative value to unsigned integer",
4060 );
4061
40624122 cases.add(
40634123 "compile-time division by zero",
40644124 \\comptime {
......@@ -4081,16 +4141,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40814141 ".tmp_source.zig:4:17: error: division by zero",
40824142 );
40834143
4084 cases.add(
4085 "compile-time integer cast truncates bits",
4086 \\comptime {
4087 \\ const spartan_count: u16 = 300;
4088 \\ const byte = @intCast(u8, spartan_count);
4089 \\}
4090 ,
4091 ".tmp_source.zig:3:18: error: cast from 'u16' to 'u8' truncates bits",
4092 );
4093
40944144 cases.add(
40954145 "@setRuntimeSafety twice for same scope",
40964146 \\export fn foo() void {
......@@ -5206,4 +5256,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52065256 ,
52075257 ".tmp_source.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic",
52085258 );
5259
5260 cases.add(
5261 "unsupported modifier at start of asm output constraint",
5262 \\export fn foo() void {
5263 \\ var bar: u32 = 3;
5264 \\ asm volatile ("" : [baz]"+r"(bar) : : "");
5265 \\}
5266 ,
5267 ".tmp_source.zig:3:5: error: invalid modifier starting output constraint for 'baz': '+', only '=' is supported. Compiler TODO: see https://github.com/ziglang/zig/issues/215",
5268 );
5269
5270 cases.add(
5271 "comptime_int in asm input",
5272 \\export fn foo() void {
5273 \\ asm volatile ("" : : [bar]"r"(3) : "");
5274 \\}
5275 ,
5276 ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_int",
5277 );
5278
5279 cases.add(
5280 "comptime_float in asm input",
5281 \\export fn foo() void {
5282 \\ asm volatile ("" : : [bar]"r"(3.17) : "");
5283 \\}
5284 ,
5285 ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_float",
5286 );
52095287}
test/runtime_safety.zig+10
......@@ -275,6 +275,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
275275 \\}
276276 );
277277
278 cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer - widening",
279 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
280 \\ @import("std").os.exit(126);
281 \\}
282 \\pub fn main() void {
283 \\ var value: c_short = -1;
284 \\ var casted = @intCast(u32, value);
285 \\}
286 );
287
278288 cases.addRuntimeSafety("unwrap error",
279289 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
280290 \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {