Packed memory has a well-defined layout that doesn't require
conversion from an integer to read from. Let's use it :-)
This change means that for bitcasting to/from a packed value that
is N layers deep, we no longer have to create N temporary big-ints
and perform N copies.
Other miscellaneous improvements:
- Adds support for casting to packed enums and vectors
- Fixes bitcasting to/from vectors outside of a packed struct
- Adds a fast path for bitcasting <= u/i64
- Fixes bug when bitcasting f80 which would clear following fields
This also changes the bitcast memory layout of exotic integers on
big-endian systems to match what's empirically observed on our targets.
Technically, this layout is not guaranteed by LLVM so we should probably
ban bitcasts that reveal these padding bits, but for now this is an
improvement.
* `?E` where E is an error set with only one field now lowers the same
as `bool`.
* Fix implementation of errUnionErrOffset and errUnionPayloadOffset to
properly compute the offset of each field. Also name them the same
as the corresponding LLVM functions and have the same function
signature, to avoid confusion. This fixes a bug where wasm was
passing the error union type instead of the payload type.
* Fix C backend handling of optionals with zero-bit payload types.
* C backend: separate out airOptionalPayload and airOptionalPayloadPtr
which reduces branching and cleans up control flow.
* Make Type.isNoReturn return true for error sets with no fields.
* Make `?error{}` have only one possible value (null).
Based on the size of the payload the native backends will lower
the error union with its fields (errorset & payload) in the correct order.
e.g. ErrorA!u8 will first lower the error set's value and then the payload.
In the event of ErrorA!u32 will lower the payload first.
This is a temporary addition to stage2 in order to match stage1 behavior,
however the end-game once the lang spec is settled will be to use a global
InternPool for comptime memoized objects, making this behavior consistent
across all types, not only string literals. Or, we might decide to not
guarantee string literals to have equal comptime pointers, in which case
this commit can be reverted.
Rename all references of sparcv9 to sparc64, to make Zig align more with
other projects. Also, added new function to convert glibc arch name to Zig
arch name, since it refers to the architecture as sparcv9.
This is based on the suggestion by @kubkon in PR 11847.
(https://github.com/ziglang/zig/pull/11487#pullrequestreview-963761757)
Rather than allocating Decl objects with an Allocator, we instead allocate
them with a SegmentedList. This provides four advantages:
* Stable memory so that one thread can access a Decl object while another
thread allocates additional Decl objects from this list.
* It allows us to use u32 indexes to reference Decl objects rather than
pointers, saving memory in Type, Value, and dependency sets.
* Using integers to reference Decl objects rather than pointers makes
serialization trivial.
* It provides a unique integer to be used for anonymous symbol names,
avoiding multi-threaded contention on an atomic counter.
Avoids many pitfalls connected with premature/early return in case
there are errors with Decl, etc. This is effectively bringing back
the old design however in a much nicer packaging, where every
mechanism related to tracking Decl's debug info is now nicely
wrapped in a single struct (aka the `DeclState`). This includes
relocation table, type arena, etc. It is now the caller's
responsibility to deinit the state (so that no memory is leaked)
after `Decl` has been analysed (or errored out). The caller here
is typically a linker such as `Elf` or `MachO`.
This implements improvements/fixes to get all the union, tuple, and array behavior tests passing.
Previously, we lowered parent pointers for field_ptr and element_ptr incompletely. This has now
been improved to recursively lower such pointer.
Also a fix was done to `generateSymbol` when checking a container's layout.
Previously it was assumed to always be a struct. However, the type can also be a tuple, and therefore
panicking. Updating to ask a type's container layout instead allows us to keep a singular branch for both cases.
Add placeholder files for Codegen, Emit, and Mir stages, complete with
a placeholder implementation of generate() to make it able to be plugged in
to the frontend. At the moment the implementation just panics, it'll be
worked on incrementally later.
Also, this registers the sparcv9 backend files into CMakeLists.txt.
Like decl code generation, also unify the wasm backend and the wasm linker to call into
the general purpose `codegen.zig` to generate the code for a function.
When an union had a zero-sized payload type, we would lower the tag twice. This is fixed
by exiting early when `payload_size` is 0.
With regards to error unions, we were only accounting for padding for the payload field.
However, the errorset value can have a smaller alignment than the payload as well, i.e. error!usize.
We fix this by also accounting for padding/alignment of the error set tag of an error union.
Several issues with pointer types are fixed:
Prior to this commit, Zig would not canonicalize a pointer type with
an explicit alignment to alignment=0 if it matched the pointee ABI
alignment. In order to fix this, `Type.ptr` now takes a Target
parameter. I also moved the host_size canonicalization to `Type.ptr`
since target is now available. Similarly, is_allowzero in the case of
C pointers is now treated as a canonicalization done by the function
rather than a precondition.
in-memory coercion for pointers now properly checks ABI alignment
of pointee types instead of incorrectly treating the 0 value as an
alignment.
Type equality is completely reworked based on the tag() rather than the
zigTypeTag(). It's still semantically based on zigTypeTag() but that
knowledge is implied rather than dictating the control flow of the
logic. Importantly, this fixes cases for opaques, structs, tuples,
enums, and unions, where type equality was incorrectly returning based
on whether the tag() values were equal.
Additionally, pointer type equality now takes into account alignment.
Because we canonicalize non-zero alignment which equals pointee type ABI
alignment to alignment=0, this now can be a simple integer comparison.
Type hashing is implemented for pointers and floats. Array types now
additionally hash their sentinels.
This regressed some behavior tests that were passing but only because
of bugs regarding type equality.
The C backend has a noticeable problem with lowering differently-aligned
pointers (particularly slices) as the same type, causing C compilation
errors due to duplicate declarations.