aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
AgeCommit message (Collapse)Author
2022-01-24stage2: rework a lot of stuffAndrew Kelley
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
2022-01-24stage2: type system treats fn ptr and body separatelyAndrew Kelley
This commit updates stage2 to enforce the property that the syntax `fn()void` is a function *body* not a *pointer*. To get a pointer, the syntax `*const fn()void` is required. ZIR puts function alignment into the func instruction rather than the decl because this way it makes it into function types. LLVM backend respects function alignments. Struct and Union have methods `fieldSrcLoc` to help look up source locations of their fields. These trigger full loading, tokenization, and parsing of source files, so should only be called once it is confirmed that an error message needs to be printed. There are some nice new error hints for explaining why a type is required to be comptime, particularly for structs that contain function body types. `Type.requiresComptime` is now moved into Sema because it can fail and might need to trigger field type resolution. Comptime pointer loading takes into account types that do not have a well-defined memory layout and does not try to compute a byte offset for them. `fn()void` syntax no longer secretly makes a pointer. You get a function body type, which requires comptime. However a pointer to a function body can be runtime known (obviously). Compile errors that report "expected pointer, found ..." are factored out into convenience functions `checkPtrOperand` and `checkPtrType` and have a note about function pointers. Implemented `Value.hash` for functions, enum literals, and undefined values. stage1 is not updated to this (yet?), so some workarounds and disabled tests are needed to keep everything working. Should we update stage1 to these new type semantics? Yes probably because I don't want to add too much conditional compilation logic in the std lib for the different backends.
2022-01-21fix incorrect zir offset loading in semaLoris Cro
2022-01-21astgen saves decl doc comments in zirLoris Cro
The field is saved in `extra` unconditionally for each decl.
2022-01-20Sema: fix requiresComptime infinite recursionAndrew Kelley
When asking a struct or union whether the type requires comptime, it may need to ask itself recursively, for example because of a field which is a pointer to itself. This commit adds a field to each to keep track of when computing the "requires comptime" value and returns `false` if the check is already ongoing.
2022-01-17Sema: fix comptime break semanticsAndrew Kelley
Previously, breaking from an outer block at comptime would result in incorrect control flow. Now there is a mechanism, `error.ComptimeBreak`, similar to `error.ComptimeReturn`, to send comptime control flow further up the stack, to its matching block. This commit also introduces a new log scope. To use it, pass `--debug-log sema_zir` and you will see 1 line per ZIR instruction semantically analyzed. This is useful when you want to understand what comptime control flow is doing while debugging the compiler. One more `switch` test case is passing.
2022-01-15stage2: fix Decl garbage collection not marking enoughAndrew Kelley
It is the job of codegen backends to mark Decls that are referenced as alive so that the frontend does not sweep them with the garbage. This commit unifies the code between the backends with an added method on Decl. The implementation is more complete than before, switching on the Decl val tag and recursing into sub-values. As a result, two more array tests are passing.
2022-01-08stage2: implement @srcRobin Voetter
2022-01-07Increment `runtime_param_index` for zero sized parametersJimmi Holst Christensen
`runtime_param_index` is used to get the parameter type from `fn_type`, but this variable was not incremented for zero sized parameters, causing two zero sized parameters of different type to cause miss complication.
2022-01-07Add two more resolution status' to Struct and UnionJimmi Holst Christensen
resolveTypeForCodegen is called when we needed to resolve a type fully, even through pointer. This commit fully implements this, even through pointer fields on structs and unions. The function has now also been renamed to resolveTypeFully
2022-01-02stage2: CacheMode.whole: trigger loading zig source filesAndrew Kelley
Previously the code asserted source files were already loaded, but this is not the case when cached ZIR is loaded. Now it will trigger .zig source code to be loaded for the purposes of hashing the source for `CacheMode.whole`. This additionally refactors stat_size, stat_inode, and stat_mtime fields into using the `Cache.File.Stat` struct.
2022-01-02stage2: add `@import` and `@embedFile` to CacheHashAndrew Kelley
when using `CacheMode.whole`. Also, I verified that `addDepFilePost` is in fact including the original C source file in addition to the files it depends on.
2022-01-02stage2: introduce CacheModeAndrew Kelley
The two CacheMode values are `whole` and `incremental`. `incremental` is what we had before; `whole` is new. Whole cache mode uses everything as inputs to the cache hash; and when a hit occurs it skips everything including linking. This is ideal for when source files change rarely and for backends that do not have good incremental compilation support, for example compiler-rt or libc compiled with LLVM with optimizations on. This is the main motivation for the additional mode, so that we can have LLVM-optimized compiler-rt/libc builds, without waiting for the LLVM backend every single time Zig is invoked. Incremental cache mode hashes only the input file path and a few target options, intentionally relying on collisions to locate already-existing build artifacts which can then be incrementally updated. The bespoke logic for caching stage1 backend build artifacts is removed since we now have a global caching mechanism for when we want to cache the entire compilation, *including* linking. Previously we had to get "creative" with libs.txt and a special byte in the hash id to communicate flags, so that when the cached artifacts were re-linked, we had this information from stage1 even though we didn't actually run it. Now that `CacheMode.whole` includes linking, this extra information does not need to be preserved for cache hits. So although this changeset introduces complexity, it also removes complexity. The main trickiness here comes from the inherent differences between the two modes: `incremental` wants a directory immediately to operate on, while `whole` doesn't know the output directory until the compilation is complete. This commit deals with this problem mostly inside `update()`, where, on a cache miss, it replaces `zig_cache_artifact_directory` with a temporary directory, and then renames it into place once the compilation is complete. Items remaining before this branch can be merged: * [ ] make sure these things make it into the cache manifest: - @import files - @embedFile files - we already add dep files from c but make sure the main .c files make it in there too, not just the included files * [ ] double check that the emit paths of other things besides the binary are working correctly. * [ ] test `-fno-emit-bin` + `-fstage1` * [ ] test `-femit-bin=foo` + `-fstage1` * [ ] implib emit directory copies bin_file_emit directory in create() and needs to be adjusted to be overridden as well. * [ ] make sure emit-h is handled correctly in the cache hash * [ ] Cache: detect duplicate files added to the manifest Some preliminary performance measurements of wall clock time and peak RSS used: stage1 behavior (1077 tests), llvm backend, release build: * cold global cache: 4.6s, 1.1 GiB * warm global cache: 3.4s, 980 MiB stage2 master branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 191 MiB * warm global cache: 0.40s, 128 MiB stage2 this branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 179 MiB * warm global cache: 0.27s, 90 MiB
2021-12-28Sema: more union fixesAndrew Kelley
* `Module.Union.getLayout`: fixes to support components of the union being 0 bits. * Implement `@typeInfo` for unions. * Add missing calls to `resolveTypeFields`. * Fix explicitly-provided union tag types passing a `Zir.Inst.Ref` where an `Air.Inst.Ref` was expected. We don't have any type safety for this; these typess are aliases. * Fix explicitly-provided `union(enum)` tag Values allocated to the wrong arena.
2021-12-28Sema: implement calling a fn ptr via a union fieldAndrew Kelley
Also, ignore `packed` on unions because that will be removed from the language.
2021-12-27stage2: fix 0-bit function parametersAndrew Kelley
Before this commit, Zig would incorrectly emit `arg` AIR instructions for parameters whose types were 0-bit.
2021-12-23stage2: initial implementation of packed structsAndrew Kelley
Layout algorithm: all `align(0)` fields are squished together as if they were a single integer with a number of bits equal to `@bitSizeOf` each field added together. Then the natural ABI alignment of that integer is used for that pseudo-field.
2021-12-21stage2: inferred error set coercionRobin Voetter
2021-12-21stage2: allow multiple inferred error sets per FnRobin Voetter
This allows the inferred error set of comptime and inline invocations to be resolved separately from the inferred error set of the runtime version or other comptime/inline invocations.
2021-12-21stage2: move inferred error set state into funcRobin Voetter
2021-12-21stage2: replace ErrorSet and ErrorSetMerged arrays with hash mapsRobin Voetter
2021-12-06stage2: improve handling of the generated file builtin.zigAndrew Kelley
All Zig code is eligible to `@import("builtin")` which is mapped to a generated file, build.zig, based on the target and other settings. Zig invocations which share the same target settings will generate the same builtin.zig file and thus the path to builtin.zig is in a shared cache folder, and different projects can sometimes use the same file. Before this commit, this led to race conditions where multiple invocations of `zig` would race to write this file. If one process wanted to *read* the file while the other process *wrote* the file, the reading process could observe a truncated or partially written builtin.zig file. This commit makes the following improvements: - limitations: - avoid clobbering the inode, mtime in the hot path - avoid creating a partially written file - builtin.zig needs to be on disk for debug info / stack trace purposes - don't mark the task as complete until the file is finished being populated (possibly by an external process) - strategy: - create the `@import("builtin")` `Module.File` during the AstGen work, based on generating the contents in memory rather than loading from disk. - write builtin.zig in a separate task that doesn't have to complete until the end of the AstGen work queue so that it can be done in parallel with everything else. - when writing the file, first stat the file path. If it exists, we are done. - otherwise, write the file to a temp file in the same directory and atomically rename it into place (clobbering the inode, mtime in the cold path). - summary: - all limitations respected - hot path: one stat() syscall that happens in a worker thread This required adding a missing function to the standard library: `std.fs.Dir.statFile`. In this commit, it does open() and then fstat() which is two syscalls. It should be improved in a future commit to only make one. Fixes #9439.
2021-12-06stage2: fix double-free when error reading cached ZIRAndrew Kelley
We already had a `keep_zir` flag. No need to call deinit manually.
2021-12-05wasm: Initial behavior tests succeedingLuuk de Gram
- Correctly load slice value on stack - Implement WrapErrorUnionErr and payload - Implement trunc, fix sliceLen and write undefined - Implement slice as return type and argument Note: This also fixes a memory leak for inferred error sets, and for usingnamespace
2021-12-04Revert "Merge pull request #10270 from Luukdegram/behaviour-tests"Andrew Kelley
This reverts commit 725267f7c20f0ba588b472048a8c1fe1a328c714, reversing changes made to 2dae860de3494f97c9477af9282fe0131ff5c4cb. This test is failing: ```zig pub fn main() u8 { var e = foo(); const i = e catch 69; return i; } fn foo() anyerror!u8 { return 5; } ``` It's returning 69 instead of the expected value 5.
2021-12-04wasm: Initial behavior tests succeedingLuuk de Gram
Note: This also fixes a memory leak for inferred error sets, and for usingnamespace
2021-12-01allocgate: use correct allocator in `populateTestFunctions`Lee Cannon
2021-11-30allocgate: renamed getAllocator function to allocatorLee Cannon
2021-11-30allocgate: stage 1 and 2 buildingLee Cannon
2021-11-30allocgate: std Allocator interface refactorLee Cannon
2021-11-30std lib API deprecations for the upcoming 0.9.0 releaseAndrew Kelley
See #3811
2021-11-24stage2: fix unwrap function call with optional pointer return valueAndrew Kelley
2021-11-24stage2: fix cleanup code for `@import` errorsAndrew Kelley
When adding test coverage, I noticed an inconsistency in which source location the compile error was pointing to for `@embedFile` errors vs `@import` errors. They now both point to the same place, the string operand. closes #9404 closes #9939
2021-11-24stage2: add cleanup logic for EmbedFileAndrew Kelley
It was never implemented, leading to a memory leak that was caught when test coverage for the compile error was added.
2021-11-21stage2: fix the build for 32-bit architecturesAndrew Kelley
* Introduce a mechanism into Sema for emitting a compile error when an integer is too big and we need it to fit into a usize. * Add `@intCast` where necessary * link/MachO: fix an unnecessary allocation when all that was happening was appending zeroes to an ArrayList. * Add `error.Overflow` as a possible error to some codepaths, allowing usage of `math.intCast`. closes #9710
2021-11-09std.Thread.Mutex: change API to lock() and unlock()Andrew Kelley
This is a breaking change. Before, usage looked like this: ```zig const held = mutex.acquire(); defer held.release(); ``` Now it looks like this: ```zig mutex.lock(); defer mutex.unlock(); ``` The `Held` type was an idea to make mutexes slightly safer by making it more difficult to forget to release an aquired lock. However, this ultimately caused more problems than it solved, when any data structures needed to store a held mutex. Simplify everything by reducing the API down to the primitives: lock() and unlock(). Closes #8051 Closes #8246 Closes #10105
2021-11-01Update ensureTotalCapacity to ensureTotalCapacityPrecise where it makes senseRyan Liptak
These calls are all late-initialization of ArrayList's that were initialized outside the current scope. This allows us to still get the potential memory-saving benefits of the 'precision' of initCapacity.
2021-10-28C backend: fix enough that zig test worksAndrew Kelley
* test_functions: properly add dependencies of the array on test functions and test names so that the order comes out correctly. * fix lowering of struct literals to add parentheses around the type name. * omit const qualifier in slices because otherwise slices cannot be reassigned even when they are local variables. * special case pointer to functions and double pointer to functions in renderTypeAndName. This code will need to be cleaned up but for now it helps us make progress on other C backend stuff. * fix slice element access to lower to `.ptr[` instead of `[`. * airSliceElemVal: respect volatile slices
2021-10-27stage2: fix small memory leak of test_functions when using `zig test`Andrew Kelley
The way `zig test` works is that it uses a stand-in var test_functions: []const TestFn = undefined; during semantic analysis, but then just before codegen, it swaps out the value with a constant like this: const test_functions: []const TestFn = .{foo, bar, baz, etc}; Before this commit, the `Module.Variable` associated with the stand-in value was leaked; now it is properly cleaned up before being replaced.
2021-10-26stage2: implement runtime pointer access to global constantsAndrew Kelley
The main problem that motivated these changes is that global constants which are referenced by pointer would not be emitted into the binary. This happened because `semaDecl` did not add `codegen_decl` tasks for global constants, instead relying on the constant values being copied as necessary. However when the global constants are referenced by pointer, they need to be sent to the linker to be emitted. After making global const arrays, structs, and unions get emitted, this uncovered a latent issue: the anonymous decls that they referenced would get garbage collected (via `deleteUnusedDecl`) even though they would later be referenced by the global const. In order to solve this problem, I introduced `anon_work_queue` which is the same as `work_queue` except a lower priority. The `codegen_decl` task for anon decls goes into the `anon_work_queue` ensuring that the owner decl gets a chance to mark its anon decls as alive before they are possibly deleted. This caused a few regressions, which I made the judgement call to add workarounds for. Two steps forward, one step back, is still progress. The regressions were: * Two behavior tests having to do with unions. These tests were intentionally exercising the LLVM constant value lowering, however, due to the bug with garbage collection that was fixed in this commit, the LLVM code was not getting exercised, and union types/values were not implemented correctly, due to me forgetting that LLVM does not allow bitcasting aggregate values. - This is worked around by allowing those 2 test cases to regress, moving them to the "passing for stage1 only" section. * The test-stage2 test cases (in test/cases/*) for non-LLVM backends previously did not have any calls to lower struct values, but now they do. The code that was there was just `@panic("TODO")`. I replaced that code with a stub that generates the wrong value. This is an intentional miscompilation that will obviously need to get fixed before any struct behavior tests pass. None of the current tests we have exercise loading any values from these global const structs, so there is not a problem until we try to improve these backends.
2021-10-22stage2: slice and alignment fixesAndrew Kelley
* Fix backend using wrong union field of the slice instruction. * LLVM backend properly sets alignment on global variables. * Sema: add coercion for *T to *[1]T * Sema: pointers to Decls with explicit alignment now have alignment metadata in them.
2021-10-22stage2: fix Decl addrspace being undefinedAndrew Kelley
2021-10-22stage2: change `@bitCast` to always be by-valueAndrew Kelley
After a discussion about language specs, this seems like the best way to go, because it's simpler to reason about both for humans and compilers. The `bitcast_result_ptr` ZIR instruction is no longer needed. This commit also implements writing enums, arrays, and vectors to virtual memory at compile-time. This unlocked some more of compiler-rt being able to build, which in turn unlocks saturating arithmetic behavior tests. There was also a memory leak in the comptime closure system which is now fixed.
2021-10-17stage2: implement `@hasField`Meghan Denny
struct and union are kept in stage1 because struct/unionFieldCount are returning zero
2021-10-17stage2: implement `@embedFile`Andrew Kelley
2021-10-17stage2: implement error wrappingAndrew Kelley
* Sema: fix returned operands not coercing to the function return type in some cases. - When returning an error or an error union from a function with an inferred error set, it will now populate the inferred error set. - Implement error set coercion for the common case of inferred error set to inferred error set, without forcing a full resolution. * LLVM backend: update instruction lowering that handles error unions to respect `isByRef`. - Also implement `wrap_err_union_err`.
2021-10-16stage2: fixes to extern variablesAndrew Kelley
* Relax compile error for "unable to export type foo" to allow integers, structs, arrays, and floats. This will need to be further improved to do the same checks as we do for C ABI struct field types. * LLVM backend: fix extern variables * LLVM backend: implement AIR instruction `wrap_err_union_payload`
2021-10-15stage2: optional comparison and 0-bit payloadsAndrew Kelley
* Sema: implement peer type resolution for optionals and null. * Rename `Module.optionalType` to `Type.optional`. * LLVM backend: re-use anonymous values. This is especially useful when isByRef()=true because it means re-using the same generated LLVM globals. * LLVM backend: rework the implementation of is_null and is_non_null AIR instructions. Generate slightly better LLVM code, and also fix the behavior for optionals whose payload type is 0-bit. * LLVM backend: improve `cmp` AIR instruction lowering to support pointer-like optionals. * `Value`: implement support for equality-checking optionals.
2021-10-14stage2: improved union supportAndrew Kelley
* `Module.Union.getFullyQualifiedName` returns a sentinel-terminated slice so that backends that need null-termination do not need an additional copy. * Module.Union: implement a `getLayout` function which returns information about ABI size and alignment so that the LLVM backend can properly lower union types into llvm types. * Sema: `resolveType` now returns `error.GenericPoison` rather than a Type with tag `generic_poison`. Callsites that want to allow that need to bypass this higher-level function. * Sema: implement coercion of enums and enum literals to unions. * Sema: fix comptime mutation of pointers to unions * LLVM backend: fully implement proper lowering of union types and values according to the union layout, and update the handling of AIR instructions that deal with unions to support union layouts. * LLVM backend: handle `decl_ref_mut` - Maybe this should be unreachable since comptime vars should be changed to be non-mutable when they go out of scope, but it's harmless for the LLVM backend to support lowering the value. * Type: fix `requiresComptime` for optionals, pointers, and some other types. This function is still wrong for structs, unions, and enums.
2021-10-13stage2: implement opaque declarationsAndrew Kelley
* Module: implement opaque type namespace lookup * Add `Type.type` for convenience * Sema: fix `validateVarType` for pointer-to-opaque * x86_64 ABI: implement support for pointers * LLVM backend: fix lowering of opaque types * Type: implement equality checking for opaques