- wip for #2046
- clang .d output must be created with `clang -MV` switch
- implemented in Zig
- hybridized for zig stage0 and stage1
- zig test src-self-hosted/dep_tokenizer.zig
stage1 translate-c actually has this wrong. When exporting a function,
it's ok to use empty parameters. But for prototypes, "no prototype"
means that it has to be emitted as a function that accepts anything,
e.g. extern fn foo(...) void;
See #1964
and use it when building libuserland.a
The self-hosted part of stage1 relies on zig's compiler-rt, and so we
include it in libuserland.a.
This should potentially be the default, but for now it's behind a linker
option.
self-hosted translate-c: small progress on translating functions.
Previously, `zig fmt` on the stage1 compiler (which is what we currently
ship) would perform what equates to `zig run std/special/fmt_runner.zig`
Now, `zig fmt` is implemented with the hybrid zig/C++ strategy outlined
by #1964.
This means Zig no longer has to ship some of the stage2 .zig files, and
there is no longer a delay when running `zig fmt` for the first time.
This modifies the build process of Zig to put all of the source files
into libcompiler.a, except main.cpp and userland.cpp.
Next, the build process links main.cpp, userland.cpp, and libcompiler.a
into zig1. userland.cpp is a shim for functions that will later be
replaced with self-hosted implementations.
Next, the build process uses zig1 to build src-self-hosted/stage1.zig
into libuserland.a, which does not depend on any of the things that
are shimmed in userland.cpp, such as translate-c.
Finally, the build process re-links main.cpp and libcompiler.a, except
with libuserland.a instead of userland.cpp. Now the shims are replaced
with .zig code. This provides all of the Zig standard library to the
stage1 C++ compiler, and enables us to move certain things to userland,
such as translate-c.
As a proof of concept I have made the `zig zen` command use text defined
in userland. I added `zig translate-c-2` which is a work-in-progress
reimplementation of translate-c in userland, which currently calls
`std.debug.panic("unimplemented")` and you can see the stack trace makes
it all the way back into the C++ main() function (Thanks LemonBoy for
improving that!).
This could potentially let us move other things into userland, such as
hashing algorithms, the entire cache system, .d file parsing, pretty
much anything that libuserland.a itself doesn't need to depend on.
This can also let us have `zig fmt` in stage1 without the overhead
of child process execution, and without the initial compilation delay
before it gets cached.
See #1964
This effectively takes one-bit from the length field and uses it as the
sign bit. It reduces the size of an Int from 40 bits to 32 bits on a
64-bit arch.
This also reduces std.Rational from 80 bits to 64 bits.
Before, allocator implementations had to provide `allocFn`,
`reallocFn`, and `freeFn`.
Now, they must provide only `reallocFn` and `shrinkFn`.
Reallocating from a zero length slice is allocation, and
shrinking to a zero length slice is freeing.
When the new memory size is less than or equal to the
previous allocation size, `reallocFn` now has the option
to return `error.OutOfMemory` to indicate that the allocator
would not be able to take advantage of the new size.
For more details see #1306. This commit closes#1306.
This commit paves the way to solving #2009.
This commit also introduces a memory leak to all coroutines.
There is an issue where a coroutine calls the function and it
frees its own stack frame, but then the return value of `shrinkFn`
is a slice, which is implemented as an sret struct. Writing to
the return pointer causes invalid memory write. We could work
around it by having a global helper function which has a void
return type and calling that instead. But instead this hack will
suffice until I rework coroutines to be non-allocating. Basically
coroutines are not supported right now until they are reworked as
in #1194.
* CLI: `-target [name]` instead of `--target-*` args.
This matches clang's API.
* `builtin.Environ` renamed to `builtin.Abi`
- likewise `builtin.environ` renamed to `builtin.abi`
* stop hiding the concept of sub-arch. closes#1526
* `zig targets` only shows available targets. closes#438
* include all targets in readme, even those that don't
print with `zig targets` but note they are Tier 4
* refactor target.cpp and make the naming conventions
more consistent
* introduce the concept of a "default C ABI" for a given
OS/Arch combo. As a rule of thumb, if the system compiler
is clang or gcc then the default C ABI is the gnu ABI.
Mostly picking the same paths as FreeBSD.
We need a little special handling for crt files, as netbsd uses its
own (and not GCC's) for those, with slightly different names.
Previously, std.debug.assert would `@panic` in test builds,
if the assertion failed. Now, it's always `unreachable`.
This makes release mode test builds more accurately test
the actual code that will be run.
However this requires tests to call `std.testing.expect`
rather than `std.debug.assert` to make sure output is correct.
Here is the explanation of when to use either one, copied from
the assert doc comments:
Inside a test block, it is best to use the `std.testing` module
rather than assert, because assert may not detect a test failure
in ReleaseFast and ReleaseSafe mode. Outside of a test block, assert
is the correct function to use.
closes#1304
* zig fmt
* std.mem.join takes a slice of slices instead of var args
* std.mem.join takes a separator slice rather than byte,
and always inserts it. Previously it would not insert the separator
if there already was one, violating the documented behavior.
* std.mem.join calculates exactly the correct amount to allocate
and has no call to allocator.shrink()
* bring back joinWindows and joinPosix and the corresponding tests.
it is intended to be able to call these functions from any OS.
* rename std.os.path.resolveSlice to resolve (now resolve takes
a slice of slices instead of var args)
* rename std.mem.split to std.mem.tokenize
* add future deprecation notice to docs
* (unrelated) add note to std.os.path.resolve docs
* std.mem.separate - assert delimiter.len not zero
* fix implementation of std.mem.separate to respect the delimiter
* separate the two iterators to different structs
`std.mem.Allocator.createOne` is renamed to `std.mem.Allocator.create`.
The problem with the previous API is that even after copy elision,
the initalization value passed as a parameter would always be a copy.
With the new API, once copy elision is done, initialization
functions can directly initialize allocated memory in place.
Related:
* #1872
* #1873
* add `@bswap` builtin function. See #767
* comptime evaluation facilities are improved to be able to
handle a `@ptrCast` with a backing array.
* `@truncate` allows "truncating" a u0 value to any integer
type, and the result is always comptime known to be `0`.
* when specifying pointer alignment in a type expression,
the alignment value of pointers which do not have addresses
at runtime is ignored, and always has the default/ABI alignment
* threw in a fix to freebsd/x86_64.zig to update syntax from
language changes
* some improvements are pending #863closes#638closes#1733
std lib API changes
* io.InStream().readIntNe renamed to readIntNative
* io.InStream().readIntLe renamed to readIntLittle
* io.InStream().readIntBe renamed to readIntBig
* introduced io.InStream().readIntForeign
* io.InStream().readInt has parameter order changed
* io.InStream().readVarInt has parameter order changed
* io.InStream().writeIntNe renamed to writeIntNative
* introduced io.InStream().writeIntForeign
* io.InStream().writeIntLe renamed to writeIntLittle
* io.InStream().writeIntBe renamed to writeIntBig
* io.InStream().writeInt has parameter order changed
* mem.readInt has different parameters and semantics
* introduced mem.readIntNative
* introduced mem.readIntForeign
* mem.readIntBE renamed to mem.readIntBig and different API
* mem.readIntLE renamed to mem.readIntLittle and different API
* introduced mem.readIntSliceNative
* introduced mem.readIntSliceForeign
* introduced mem.readIntSliceLittle
* introduced mem.readIntSliceBig
* introduced mem.readIntSlice
* mem.writeInt has different parameters and semantics
* introduced mem.writeIntNative
* introduced mem.writeIntForeign
* mem.writeIntBE renamed to mem.readIntBig and different semantics
* mem.writeIntLE renamed to mem.readIntLittle and different semantics
* introduced mem.writeIntSliceForeign
* introduced mem.writeIntSliceNative
* introduced mem.writeIntSliceBig
* introduced mem.writeIntSliceLittle
* introduced mem.writeIntSlice
* removed mem.endianSwapIfLe
* removed mem.endianSwapIfBe
* removed mem.endianSwapIf
* added mem.littleToNative
* added mem.bigToNative
* added mem.toNative
* added mem.nativeTo
* added mem.nativeToLittle
* added mem.nativeToBig
* error.BadFd is not a valid error code. it would always be a bug to
get this error code.
* merge error.Io with existing error.InputOutput
* merge error.PathNotFound with existing error.FileNotFound.
Not all OS's support both.
* add os.File.openReadC
* add error.BadPathName for windows file operations with invalid
characters
* add os.toPosixPath to help stack allocate a null terminating byte
* add some TODOs for other functions to investigate removing the
allocator requirement
* optimize some implementations to use the alternate functions when
a null byte is already available
* add a missing error.SkipZigTest
* os.selfExePath uses a non-allocating API
* os.selfExeDirPath uses a non-allocating API
* os.path.real uses a non-allocating API
* add os.path.realAlloc and os.path.realC
* convert many windows syscalls to use the W versions (See #534)