aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-07 00:39:23 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-07 00:39:23 -0700
commit13f04e3012b6b2eee141923f9780fce55f7a999d (patch)
treefd8d164d7926d76a1e967b89283322ee6ad88bb0 /src/value.zig
parentd481acc7dbebb5501b5fef608ee1f6b13c442c6a (diff)
downloadzig-13f04e3012b6b2eee141923f9780fce55f7a999d.tar.gz
zig-13f04e3012b6b2eee141923f9780fce55f7a999d.zip
stage2: implement `@panic` and beginnigs of inferred error sets
* ZIR: add two instructions: - ret_err_value_code - ret_err_value * AstGen: add countDefers and utilize it to emit more efficient ZIR for return expressions in the presence of defers. * AstGen: implement |err| payloads for `errdefer` syntax. - There is not an "unused capture" error for it yet. * AstGen: `return error.Foo` syntax gets a hot path in return expressions, using the new ZIR instructions. This also is part of implementing inferred error sets, since we need to tell Sema to add an error value to the inferred error set before it gets coerced. * Sema: implement `@setCold`. - Implement `@setCold` support for C backend. * `@panic` and regular safety panics such as `unreachable` now properly invoke `std.builtin.panic`. * C backend: improve pointer and function value rendering. * C linker: fix redundant typedefs. * Add Type.error_set_inferred. * Fix Value.format for enum_literal, enum_field_index, bytes. * Remove the C backend test that checks for identical text I measured a 14% reduction in Total ZIR Bytes from master branch for std/os.zig.
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/value.zig b/src/value.zig
index 008cc3c2fe..b4cd63b8d3 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -483,13 +483,13 @@ pub const Value = extern union {
/// TODO this should become a debug dump() function. In order to print values in a meaningful way
/// we also need access to the type.
pub fn format(
- self: Value,
+ start_val: Value,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
out_stream: anytype,
) !void {
comptime assert(fmt.len == 0);
- var val = self;
+ var val = start_val;
while (true) switch (val.tag()) {
.u8_type => return out_stream.writeAll("u8"),
.i8_type => return out_stream.writeAll("i8"),
@@ -598,9 +598,9 @@ pub const Value = extern union {
val = field_ptr.container_ptr;
},
.empty_array => return out_stream.writeAll(".{}"),
- .enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(self.castTag(.enum_literal).?.data)}),
- .enum_field_index => return out_stream.print("(enum field {d})", .{self.castTag(.enum_field_index).?.data}),
- .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(self.castTag(.bytes).?.data)}),
+ .enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),
+ .enum_field_index => return out_stream.print("(enum field {d})", .{val.castTag(.enum_field_index).?.data}),
+ .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
.repeated => {
try out_stream.writeAll("(repeated) ");
val = val.castTag(.repeated).?.data;
@@ -1336,6 +1336,23 @@ pub const Value = extern union {
};
}
+ pub fn sliceLen(val: Value) u64 {
+ return switch (val.tag()) {
+ .empty_array => 0,
+ .bytes => val.castTag(.bytes).?.data.len,
+ .ref_val => sliceLen(val.castTag(.ref_val).?.data),
+ .decl_ref => {
+ const decl = val.castTag(.decl_ref).?.data;
+ if (decl.ty.zigTypeTag() == .Array) {
+ return decl.ty.arrayLen();
+ } else {
+ return 1;
+ }
+ },
+ else => unreachable,
+ };
+ }
+
/// Asserts the value is a single-item pointer to an array, or an array,
/// or an unknown-length pointer, and returns the element value at the index.
pub fn elemValue(self: Value, allocator: *Allocator, index: usize) error{OutOfMemory}!Value {