mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
Merge remote-tracking branch 'origin/master' into llvm10
This commit is contained in:
+3
-13
@@ -5,18 +5,6 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif()
|
||||
|
||||
set(_list "None;Debug;Release;RelWithDebInfo;MinSizeRel")
|
||||
list(FIND _list ${CMAKE_BUILD_TYPE} _index)
|
||||
if(${_index} EQUAL -1)
|
||||
string(REPLACE ";" ", " _list_pretty "${_list}")
|
||||
message("::")
|
||||
message(":: ERROR: Invalid build type: ${CMAKE_BUILD_TYPE}")
|
||||
message("::")
|
||||
message(":: valid types: { ${_list_pretty} }")
|
||||
message("::")
|
||||
message(FATAL_ERROR)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE STRING
|
||||
"Directory to install zig to" FORCE)
|
||||
@@ -256,7 +244,7 @@ set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
|
||||
set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
|
||||
|
||||
if(ZIG_ENABLE_MEM_PROFILE)
|
||||
set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/memory_profiling.cpp")
|
||||
set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp")
|
||||
endif()
|
||||
|
||||
set(ZIG_SOURCES
|
||||
@@ -272,10 +260,12 @@ set(ZIG_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/errmsg.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/error.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/glibc.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/heap.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/ir.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/link.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/mem.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/os.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/parser.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/range_set.cpp"
|
||||
|
||||
+3
-11
@@ -244,10 +244,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
|
||||
}
|
||||
|
||||
test "std.ArrayList.init" {
|
||||
var bytes: [1024]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
|
||||
var list = ArrayList(i32).init(allocator);
|
||||
var list = ArrayList(i32).init(testing.allocator);
|
||||
defer list.deinit();
|
||||
|
||||
testing.expect(list.len == 0);
|
||||
@@ -255,19 +252,14 @@ test "std.ArrayList.init" {
|
||||
}
|
||||
|
||||
test "std.ArrayList.initCapacity" {
|
||||
var bytes: [1024]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
var list = try ArrayList(i8).initCapacity(allocator, 200);
|
||||
var list = try ArrayList(i8).initCapacity(testing.allocator, 200);
|
||||
defer list.deinit();
|
||||
testing.expect(list.len == 0);
|
||||
testing.expect(list.capacity() >= 200);
|
||||
}
|
||||
|
||||
test "std.ArrayList.basic" {
|
||||
var bytes: [1024]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
|
||||
var list = ArrayList(i32).init(allocator);
|
||||
var list = ArrayList(i32).init(testing.allocator);
|
||||
defer list.deinit();
|
||||
|
||||
// setting on empty list is out of bounds
|
||||
|
||||
+2
-3
@@ -236,9 +236,8 @@ pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8)
|
||||
}
|
||||
|
||||
test "allocLowerString" {
|
||||
var buf: [100]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
const result = try allocLowerString(allocator, "aBcDeFgHiJkLmNOPqrst0234+💩!");
|
||||
const result = try allocLowerString(std.testing.allocator, "aBcDeFgHiJkLmNOPqrst0234+💩!");
|
||||
defer std.testing.allocator.free(result);
|
||||
std.testing.expect(std.mem.eql(u8, "abcdefghijklmnopqrst0234+💩!", result));
|
||||
}
|
||||
|
||||
|
||||
+13
-3
@@ -651,6 +651,7 @@ pub const Tokenizer = struct {
|
||||
state = .StringLiteral;
|
||||
},
|
||||
else => {
|
||||
self.index -= 1;
|
||||
state = .Identifier;
|
||||
},
|
||||
},
|
||||
@@ -660,6 +661,7 @@ pub const Tokenizer = struct {
|
||||
state = .StringLiteral;
|
||||
},
|
||||
else => {
|
||||
self.index -= 1;
|
||||
state = .Identifier;
|
||||
},
|
||||
},
|
||||
@@ -673,6 +675,7 @@ pub const Tokenizer = struct {
|
||||
state = .StringLiteral;
|
||||
},
|
||||
else => {
|
||||
self.index -= 1;
|
||||
state = .Identifier;
|
||||
},
|
||||
},
|
||||
@@ -686,6 +689,7 @@ pub const Tokenizer = struct {
|
||||
state = .StringLiteral;
|
||||
},
|
||||
else => {
|
||||
self.index -= 1;
|
||||
state = .Identifier;
|
||||
},
|
||||
},
|
||||
@@ -1079,6 +1083,9 @@ pub const Tokenizer = struct {
|
||||
'x', 'X' => {
|
||||
state = .IntegerLiteralHex;
|
||||
},
|
||||
'.' => {
|
||||
state = .FloatFraction;
|
||||
},
|
||||
else => {
|
||||
state = .IntegerSuffix;
|
||||
self.index -= 1;
|
||||
@@ -1261,13 +1268,16 @@ pub const Tokenizer = struct {
|
||||
.UnicodeEscape,
|
||||
.MultiLineComment,
|
||||
.MultiLineCommentAsterisk,
|
||||
.FloatFraction,
|
||||
.FloatFractionHex,
|
||||
.FloatExponent,
|
||||
.FloatExponentDigits,
|
||||
.MacroString,
|
||||
=> result.id = .Invalid,
|
||||
|
||||
.FloatExponentDigits => result.id = if (counter == 0) .Invalid else .{ .FloatLiteral = .None },
|
||||
|
||||
.FloatFraction,
|
||||
.FloatFractionHex,
|
||||
=> result.id = .{ .FloatLiteral = .None },
|
||||
|
||||
.IntegerLiteralOct,
|
||||
.IntegerLiteralBinary,
|
||||
.IntegerLiteralHex,
|
||||
|
||||
+2
-3
@@ -41,9 +41,8 @@ pub fn addNullByte(allocator: *mem.Allocator, slice: []const u8) ![:0]u8 {
|
||||
}
|
||||
|
||||
test "addNullByte" {
|
||||
var buf: [30]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
const slice = try addNullByte(allocator, "hello"[0..4]);
|
||||
const slice = try addNullByte(std.testing.allocator, "hello"[0..4]);
|
||||
defer std.testing.allocator.free(slice);
|
||||
testing.expect(slice.len == 4);
|
||||
testing.expect(slice[4] == 0);
|
||||
}
|
||||
|
||||
+50
-6
@@ -69,12 +69,12 @@ fn peekIsAlign(comptime fmt: []const u8) bool {
|
||||
///
|
||||
/// If a formatted user type contains a function of the type
|
||||
/// ```
|
||||
/// fn format(value: ?, comptime fmt: []const u8, options: std.fmt.FormatOptions, context: var, comptime Errors: type, output: fn (@TypeOf(context), []const u8) Errors!void) Errors!void
|
||||
/// fn format(value: ?, comptime fmt: []const u8, options: std.fmt.FormatOptions, context: var, comptime Errors: type, comptime output: fn (@TypeOf(context), []const u8) Errors!void) Errors!void
|
||||
/// ```
|
||||
/// with `?` being the type formatted, this function will be called instead of the default implementation.
|
||||
/// This allows user types to be formatted in a logical manner instead of dumping all fields of the type.
|
||||
///
|
||||
/// A user type may be a `struct`, `union` or `enum` type.
|
||||
/// A user type may be a `struct`, `vector`, `union` or `enum` type.
|
||||
pub fn format(
|
||||
context: var,
|
||||
comptime Errors: type,
|
||||
@@ -373,11 +373,11 @@ pub fn formatType(
|
||||
try output(context, @typeName(T));
|
||||
if (enumInfo.is_exhaustive) {
|
||||
try output(context, ".");
|
||||
return formatType(@tagName(value), "", options, context, Errors, output, max_depth);
|
||||
try output(context, @tagName(value));
|
||||
} else {
|
||||
// TODO: when @tagName works on exhaustive enums print known enum strings
|
||||
try output(context, "(");
|
||||
try formatType(@enumToInt(value), "", options, context, Errors, output, max_depth);
|
||||
try formatType(@enumToInt(value), fmt, options, context, Errors, output, max_depth);
|
||||
try output(context, ")");
|
||||
}
|
||||
},
|
||||
@@ -397,7 +397,7 @@ pub fn formatType(
|
||||
try output(context, " = ");
|
||||
inline for (info.fields) |u_field| {
|
||||
if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
|
||||
try formatType(@field(value, u_field.name), "", options, context, Errors, output, max_depth - 1);
|
||||
try formatType(@field(value, u_field.name), fmt, options, context, Errors, output, max_depth - 1);
|
||||
}
|
||||
}
|
||||
try output(context, " }");
|
||||
@@ -424,7 +424,7 @@ pub fn formatType(
|
||||
}
|
||||
try output(context, @memberName(T, field_i));
|
||||
try output(context, " = ");
|
||||
try formatType(@field(value, @memberName(T, field_i)), "", options, context, Errors, output, max_depth - 1);
|
||||
try formatType(@field(value, @memberName(T, field_i)), fmt, options, context, Errors, output, max_depth - 1);
|
||||
}
|
||||
try output(context, " }");
|
||||
},
|
||||
@@ -474,6 +474,18 @@ pub fn formatType(
|
||||
});
|
||||
return formatType(@as(Slice, &value), fmt, options, context, Errors, output, max_depth);
|
||||
},
|
||||
.Vector => {
|
||||
const len = @typeInfo(T).Vector.len;
|
||||
try output(context, "{ ");
|
||||
var i: usize = 0;
|
||||
while (i < len) : (i += 1) {
|
||||
try formatValue(value[i], fmt, options, context, Errors, output);
|
||||
if (i < len - 1) {
|
||||
try output(context, ", ");
|
||||
}
|
||||
}
|
||||
try output(context, " }");
|
||||
},
|
||||
.Fn => {
|
||||
return format(context, Errors, output, "{}@{x}", .{ @typeName(T), @ptrToInt(value) });
|
||||
},
|
||||
@@ -500,6 +512,7 @@ fn formatValue(
|
||||
switch (@typeId(T)) {
|
||||
.Float => return formatFloatValue(value, fmt, options, context, Errors, output),
|
||||
.Int, .ComptimeInt => return formatIntValue(value, fmt, options, context, Errors, output),
|
||||
.Bool => return output(context, if (value) "true" else "false"),
|
||||
else => comptime unreachable,
|
||||
}
|
||||
}
|
||||
@@ -1343,6 +1356,20 @@ test "enum" {
|
||||
try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
|
||||
}
|
||||
|
||||
test "non-exhaustive enum" {
|
||||
const Enum = enum(u16) {
|
||||
One = 0x000f,
|
||||
Two = 0xbeef,
|
||||
_,
|
||||
};
|
||||
try testFmt("enum: Enum(15)\n", "enum: {}\n", .{Enum.One});
|
||||
try testFmt("enum: Enum(48879)\n", "enum: {}\n", .{Enum.Two});
|
||||
try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
|
||||
try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One});
|
||||
try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two});
|
||||
try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
|
||||
}
|
||||
|
||||
test "float.scientific" {
|
||||
try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)});
|
||||
try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)});
|
||||
@@ -1699,3 +1726,20 @@ test "positional with specifier" {
|
||||
test "positional/alignment/width/precision" {
|
||||
try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)});
|
||||
}
|
||||
|
||||
test "vector" {
|
||||
// https://github.com/ziglang/zig/issues/3317
|
||||
if (builtin.arch == .mipsel) return error.SkipZigTest;
|
||||
|
||||
const vbool: @Vector(4, bool) = [_]bool{ true, false, true, false };
|
||||
const vi64: @Vector(4, i64) = [_]i64{ -2, -1, 0, 1 };
|
||||
const vu64: @Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 };
|
||||
|
||||
try testFmt("{ true, false, true, false }", "{}", .{vbool});
|
||||
try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64});
|
||||
try testFmt("{ - 2, - 1, + 0, + 1 }", "{d:5}", .{vi64});
|
||||
try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64});
|
||||
try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64});
|
||||
try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64});
|
||||
try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64});
|
||||
}
|
||||
|
||||
@@ -56,9 +56,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
|
||||
}
|
||||
|
||||
test "getAppDataDir" {
|
||||
var buf: [512]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
|
||||
|
||||
// We can't actually validate the result
|
||||
_ = getAppDataDir(allocator, "zig") catch return;
|
||||
const dir = getAppDataDir(std.testing.allocator, "zig") catch return;
|
||||
defer std.testing.allocator.free(dir);
|
||||
}
|
||||
|
||||
+4
-6
@@ -89,16 +89,14 @@ pub fn joinPosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
|
||||
}
|
||||
|
||||
fn testJoinWindows(paths: []const []const u8, expected: []const u8) void {
|
||||
var buf: [1024]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
const actual = joinWindows(a, paths) catch @panic("fail");
|
||||
const actual = joinWindows(testing.allocator, paths) catch @panic("fail");
|
||||
defer testing.allocator.free(actual);
|
||||
testing.expectEqualSlices(u8, expected, actual);
|
||||
}
|
||||
|
||||
fn testJoinPosix(paths: []const []const u8, expected: []const u8) void {
|
||||
var buf: [1024]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
const actual = joinPosix(a, paths) catch @panic("fail");
|
||||
const actual = joinPosix(testing.allocator, paths) catch @panic("fail");
|
||||
defer testing.allocator.free(actual);
|
||||
testing.expectEqualSlices(u8, expected, actual);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -533,7 +533,7 @@ pub const ArenaAllocator = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *ArenaAllocator) void {
|
||||
pub fn deinit(self: ArenaAllocator) void {
|
||||
var it = self.buffer_list.first;
|
||||
while (it) |node| {
|
||||
// this has to occur before the free because the free frees node
|
||||
|
||||
+22
-26
@@ -83,12 +83,8 @@ const HeaderEntry = struct {
|
||||
}
|
||||
};
|
||||
|
||||
var test_memory: [32 * 1024]u8 = undefined;
|
||||
var test_fba_state = std.heap.FixedBufferAllocator.init(&test_memory);
|
||||
const test_allocator = &test_fba_state.allocator;
|
||||
|
||||
test "HeaderEntry" {
|
||||
var e = try HeaderEntry.init(test_allocator, "foo", "bar", null);
|
||||
var e = try HeaderEntry.init(testing.allocator, "foo", "bar", null);
|
||||
defer e.deinit();
|
||||
testing.expectEqualSlices(u8, "foo", e.name);
|
||||
testing.expectEqualSlices(u8, "bar", e.value);
|
||||
@@ -368,7 +364,7 @@ pub const Headers = struct {
|
||||
};
|
||||
|
||||
test "Headers.iterator" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("cookie", "somevalue", null);
|
||||
@@ -390,7 +386,7 @@ test "Headers.iterator" {
|
||||
}
|
||||
|
||||
test "Headers.contains" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("cookie", "somevalue", null);
|
||||
@@ -400,7 +396,7 @@ test "Headers.contains" {
|
||||
}
|
||||
|
||||
test "Headers.delete" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("baz", "qux", null);
|
||||
@@ -428,7 +424,7 @@ test "Headers.delete" {
|
||||
}
|
||||
|
||||
test "Headers.orderedRemove" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("baz", "qux", null);
|
||||
@@ -451,7 +447,7 @@ test "Headers.orderedRemove" {
|
||||
}
|
||||
|
||||
test "Headers.swapRemove" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("baz", "qux", null);
|
||||
@@ -474,7 +470,7 @@ test "Headers.swapRemove" {
|
||||
}
|
||||
|
||||
test "Headers.at" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("cookie", "somevalue", null);
|
||||
@@ -494,7 +490,7 @@ test "Headers.at" {
|
||||
}
|
||||
|
||||
test "Headers.getIndices" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("set-cookie", "x=1", null);
|
||||
@@ -506,27 +502,27 @@ test "Headers.getIndices" {
|
||||
}
|
||||
|
||||
test "Headers.get" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("set-cookie", "x=1", null);
|
||||
try h.append("set-cookie", "y=2", null);
|
||||
|
||||
{
|
||||
const v = try h.get(test_allocator, "not-present");
|
||||
const v = try h.get(testing.allocator, "not-present");
|
||||
testing.expect(null == v);
|
||||
}
|
||||
{
|
||||
const v = (try h.get(test_allocator, "foo")).?;
|
||||
defer test_allocator.free(v);
|
||||
const v = (try h.get(testing.allocator, "foo")).?;
|
||||
defer testing.allocator.free(v);
|
||||
const e = v[0];
|
||||
testing.expectEqualSlices(u8, "foo", e.name);
|
||||
testing.expectEqualSlices(u8, "bar", e.value);
|
||||
testing.expectEqual(false, e.never_index);
|
||||
}
|
||||
{
|
||||
const v = (try h.get(test_allocator, "set-cookie")).?;
|
||||
defer test_allocator.free(v);
|
||||
const v = (try h.get(testing.allocator, "set-cookie")).?;
|
||||
defer testing.allocator.free(v);
|
||||
{
|
||||
const e = v[0];
|
||||
testing.expectEqualSlices(u8, "set-cookie", e.name);
|
||||
@@ -543,30 +539,30 @@ test "Headers.get" {
|
||||
}
|
||||
|
||||
test "Headers.getCommaSeparated" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("set-cookie", "x=1", null);
|
||||
try h.append("set-cookie", "y=2", null);
|
||||
|
||||
{
|
||||
const v = try h.getCommaSeparated(test_allocator, "not-present");
|
||||
const v = try h.getCommaSeparated(testing.allocator, "not-present");
|
||||
testing.expect(null == v);
|
||||
}
|
||||
{
|
||||
const v = (try h.getCommaSeparated(test_allocator, "foo")).?;
|
||||
defer test_allocator.free(v);
|
||||
const v = (try h.getCommaSeparated(testing.allocator, "foo")).?;
|
||||
defer testing.allocator.free(v);
|
||||
testing.expectEqualSlices(u8, "bar", v);
|
||||
}
|
||||
{
|
||||
const v = (try h.getCommaSeparated(test_allocator, "set-cookie")).?;
|
||||
defer test_allocator.free(v);
|
||||
const v = (try h.getCommaSeparated(testing.allocator, "set-cookie")).?;
|
||||
defer testing.allocator.free(v);
|
||||
testing.expectEqualSlices(u8, "x=1,y=2", v);
|
||||
}
|
||||
}
|
||||
|
||||
test "Headers.sort" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("cookie", "somevalue", null);
|
||||
@@ -587,7 +583,7 @@ test "Headers.sort" {
|
||||
}
|
||||
|
||||
test "Headers.format" {
|
||||
var h = Headers.init(test_allocator);
|
||||
var h = Headers.init(testing.allocator);
|
||||
defer h.deinit();
|
||||
try h.append("foo", "bar", null);
|
||||
try h.append("cookie", "somevalue", null);
|
||||
|
||||
+4
-8
@@ -223,15 +223,13 @@ test "io.BufferedInStream" {
|
||||
}
|
||||
};
|
||||
|
||||
var buf: [100]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
|
||||
|
||||
const str = "This is a test";
|
||||
var one_byte_stream = OneByteReadInStream.init(str);
|
||||
var buf_in_stream = BufferedInStream(OneByteReadInStream.Error).init(&one_byte_stream.stream);
|
||||
const stream = &buf_in_stream.stream;
|
||||
|
||||
const res = try stream.readAllAlloc(allocator, str.len + 1);
|
||||
const res = try stream.readAllAlloc(testing.allocator, str.len + 1);
|
||||
defer testing.allocator.free(res);
|
||||
testing.expectEqualSlices(u8, str, res);
|
||||
}
|
||||
|
||||
@@ -874,10 +872,8 @@ pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
|
||||
}
|
||||
|
||||
test "io.readLineFrom" {
|
||||
var bytes: [128]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
var buf = try std.Buffer.initSize(testing.allocator, 0);
|
||||
defer buf.deinit();
|
||||
var mem_stream = SliceInStream.init(
|
||||
\\Line 1
|
||||
\\Line 22
|
||||
|
||||
+4
-9
@@ -11,9 +11,6 @@ const fs = std.fs;
|
||||
const File = std.fs.File;
|
||||
|
||||
test "write a file, read it, then delete it" {
|
||||
var raw_bytes: [200 * 1024]u8 = undefined;
|
||||
var allocator = &std.heap.FixedBufferAllocator.init(raw_bytes[0..]).allocator;
|
||||
|
||||
const cwd = fs.cwd();
|
||||
|
||||
var data: [1024]u8 = undefined;
|
||||
@@ -53,8 +50,8 @@ test "write a file, read it, then delete it" {
|
||||
var file_in_stream = file.inStream();
|
||||
var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream);
|
||||
const st = &buf_stream.stream;
|
||||
const contents = try st.readAllAlloc(allocator, 2 * 1024);
|
||||
defer allocator.free(contents);
|
||||
const contents = try st.readAllAlloc(std.testing.allocator, 2 * 1024);
|
||||
defer std.testing.allocator.free(contents);
|
||||
|
||||
expect(mem.eql(u8, contents[0.."begin".len], "begin"));
|
||||
expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data));
|
||||
@@ -64,10 +61,8 @@ test "write a file, read it, then delete it" {
|
||||
}
|
||||
|
||||
test "BufferOutStream" {
|
||||
var bytes: [100]u8 = undefined;
|
||||
var allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
|
||||
var buffer = try std.Buffer.initSize(allocator, 0);
|
||||
var buffer = try std.Buffer.initSize(std.testing.allocator, 0);
|
||||
defer buffer.deinit();
|
||||
var buf_stream = &std.io.BufferOutStream.init(&buffer).stream;
|
||||
|
||||
const x: i32 = 42;
|
||||
|
||||
+20
-22
@@ -1495,10 +1495,7 @@ fn unescapeString(output: []u8, input: []const u8) !void {
|
||||
}
|
||||
|
||||
test "json.parser.dynamic" {
|
||||
var memory: [1024 * 16]u8 = undefined;
|
||||
var buf_alloc = std.heap.FixedBufferAllocator.init(&memory);
|
||||
|
||||
var p = Parser.init(&buf_alloc.allocator, false);
|
||||
var p = Parser.init(testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
const s =
|
||||
@@ -1588,10 +1585,10 @@ test "write json then parse it" {
|
||||
|
||||
try jw.endObject();
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var parser = Parser.init(allocator, false);
|
||||
const tree = try parser.parse(slice_out_stream.getWritten());
|
||||
var parser = Parser.init(testing.allocator, false);
|
||||
defer parser.deinit();
|
||||
var tree = try parser.parse(slice_out_stream.getWritten());
|
||||
defer tree.deinit();
|
||||
|
||||
testing.expect(tree.root.Object.get("f").?.value.Bool == false);
|
||||
testing.expect(tree.root.Object.get("t").?.value.Bool == true);
|
||||
@@ -1601,21 +1598,21 @@ test "write json then parse it" {
|
||||
testing.expect(mem.eql(u8, tree.root.Object.get("str").?.value.String, "hello"));
|
||||
}
|
||||
|
||||
fn test_parse(memory: []u8, json_str: []const u8) !Value {
|
||||
// buf_alloc goes out of scope, but we don't use it after parsing
|
||||
var buf_alloc = std.heap.FixedBufferAllocator.init(memory);
|
||||
var p = Parser.init(&buf_alloc.allocator, false);
|
||||
fn test_parse(arena_allocator: *std.mem.Allocator, json_str: []const u8) !Value {
|
||||
var p = Parser.init(arena_allocator, false);
|
||||
return (try p.parse(json_str)).root;
|
||||
}
|
||||
|
||||
test "parsing empty string gives appropriate error" {
|
||||
var memory: [1024 * 4]u8 = undefined;
|
||||
testing.expectError(error.UnexpectedEndOfJson, test_parse(&memory, ""));
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
testing.expectError(error.UnexpectedEndOfJson, test_parse(&arena_allocator.allocator, ""));
|
||||
}
|
||||
|
||||
test "integer after float has proper type" {
|
||||
var memory: [1024 * 8]u8 = undefined;
|
||||
const json = try test_parse(&memory,
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
const json = try test_parse(&arena_allocator.allocator,
|
||||
\\{
|
||||
\\ "float": 3.14,
|
||||
\\ "ints": [1, 2, 3]
|
||||
@@ -1625,7 +1622,8 @@ test "integer after float has proper type" {
|
||||
}
|
||||
|
||||
test "escaped characters" {
|
||||
var memory: [1024 * 16]u8 = undefined;
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
const input =
|
||||
\\{
|
||||
\\ "backslash": "\\",
|
||||
@@ -1641,7 +1639,7 @@ test "escaped characters" {
|
||||
\\}
|
||||
;
|
||||
|
||||
const obj = (try test_parse(&memory, input)).Object;
|
||||
const obj = (try test_parse(&arena_allocator.allocator, input)).Object;
|
||||
|
||||
testing.expectEqualSlices(u8, obj.get("backslash").?.value.String, "\\");
|
||||
testing.expectEqualSlices(u8, obj.get("forwardslash").?.value.String, "/");
|
||||
@@ -1665,13 +1663,13 @@ test "string copy option" {
|
||||
\\}
|
||||
;
|
||||
|
||||
var mem_buffer: [1024 * 16]u8 = undefined;
|
||||
var buf_alloc = std.heap.FixedBufferAllocator.init(&mem_buffer);
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
|
||||
const tree_nocopy = try Parser.init(&buf_alloc.allocator, false).parse(input);
|
||||
const tree_nocopy = try Parser.init(&arena_allocator.allocator, false).parse(input);
|
||||
const obj_nocopy = tree_nocopy.root.Object;
|
||||
|
||||
const tree_copy = try Parser.init(&buf_alloc.allocator, true).parse(input);
|
||||
const tree_copy = try Parser.init(&arena_allocator.allocator, true).parse(input);
|
||||
const obj_copy = tree_copy.root.Object;
|
||||
|
||||
for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {
|
||||
|
||||
+14
-17
@@ -8,19 +8,18 @@ const std = @import("../std.zig");
|
||||
fn ok(comptime s: []const u8) void {
|
||||
std.testing.expect(std.json.validate(s));
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var p = std.json.Parser.init(allocator, false);
|
||||
var p = std.json.Parser.init(std.testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
_ = p.parse(s) catch unreachable;
|
||||
var tree = p.parse(s) catch unreachable;
|
||||
defer tree.deinit();
|
||||
}
|
||||
|
||||
fn err(comptime s: []const u8) void {
|
||||
std.testing.expect(!std.json.validate(s));
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var p = std.json.Parser.init(allocator, false);
|
||||
var p = std.json.Parser.init(std.testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
if (p.parse(s)) |_| {
|
||||
unreachable;
|
||||
@@ -30,9 +29,8 @@ fn err(comptime s: []const u8) void {
|
||||
fn utf8Error(comptime s: []const u8) void {
|
||||
std.testing.expect(!std.json.validate(s));
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var p = std.json.Parser.init(allocator, false);
|
||||
var p = std.json.Parser.init(std.testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
if (p.parse(s)) |_| {
|
||||
unreachable;
|
||||
@@ -44,19 +42,18 @@ fn utf8Error(comptime s: []const u8) void {
|
||||
fn any(comptime s: []const u8) void {
|
||||
_ = std.json.validate(s);
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var p = std.json.Parser.init(allocator, false);
|
||||
var p = std.json.Parser.init(std.testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
_ = p.parse(s) catch {};
|
||||
var tree = p.parse(s) catch return;
|
||||
defer tree.deinit();
|
||||
}
|
||||
|
||||
fn anyStreamingErrNonStreaming(comptime s: []const u8) void {
|
||||
_ = std.json.validate(s);
|
||||
|
||||
var mem_buffer: [1024 * 20]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator;
|
||||
var p = std.json.Parser.init(allocator, false);
|
||||
var p = std.json.Parser.init(std.testing.allocator, false);
|
||||
defer p.deinit();
|
||||
|
||||
if (p.parse(s)) |_| {
|
||||
unreachable;
|
||||
|
||||
@@ -254,11 +254,11 @@ test "json write stream" {
|
||||
var slice_stream = std.io.SliceOutStream.init(&out_buf);
|
||||
const out = &slice_stream.stream;
|
||||
|
||||
var mem_buf: [1024 * 10]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&mem_buf).allocator;
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
|
||||
var w = std.json.WriteStream(@TypeOf(out).Child, 10).init(out);
|
||||
try w.emitJson(try getJson(allocator));
|
||||
try w.emitJson(try getJson(&arena_allocator.allocator));
|
||||
|
||||
const result = slice_stream.getWritten();
|
||||
const expected =
|
||||
|
||||
+488
-247
@@ -137,10 +137,9 @@ pub const Int = struct {
|
||||
}
|
||||
|
||||
/// Frees all memory associated with an Int.
|
||||
pub fn deinit(self: *Int) void {
|
||||
pub fn deinit(self: Int) void {
|
||||
self.assertWritable();
|
||||
self.allocator.?.free(self.limbs);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
/// Clones an Int and returns a new Int with the same value. The new Int is a deep copy and
|
||||
@@ -1361,13 +1360,10 @@ pub const Int = struct {
|
||||
// They will still run on larger than this and should pass, but the multi-limb code-paths
|
||||
// may be untested in some cases.
|
||||
|
||||
var buffer: [64 * 8192]u8 = undefined;
|
||||
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
|
||||
const al = &fixed.allocator;
|
||||
|
||||
test "big.int comptime_int set" {
|
||||
comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
|
||||
var a = try Int.initSet(al, s);
|
||||
var a = try Int.initSet(testing.allocator, s);
|
||||
defer a.deinit();
|
||||
|
||||
const s_limb_count = 128 / Limb.bit_count;
|
||||
|
||||
@@ -1381,39 +1377,45 @@ test "big.int comptime_int set" {
|
||||
}
|
||||
|
||||
test "big.int comptime_int set negative" {
|
||||
var a = try Int.initSet(al, -10);
|
||||
var a = try Int.initSet(testing.allocator, -10);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expect(a.limbs[0] == 10);
|
||||
testing.expect(a.isPositive() == false);
|
||||
}
|
||||
|
||||
test "big.int int set unaligned small" {
|
||||
var a = try Int.initSet(al, @as(u7, 45));
|
||||
var a = try Int.initSet(testing.allocator, @as(u7, 45));
|
||||
defer a.deinit();
|
||||
|
||||
testing.expect(a.limbs[0] == 45);
|
||||
testing.expect(a.isPositive() == true);
|
||||
}
|
||||
|
||||
test "big.int comptime_int to" {
|
||||
const a = try Int.initSet(al, 0xefffffff00000001eeeeeeefaaaaaaab);
|
||||
const a = try Int.initSet(testing.allocator, 0xefffffff00000001eeeeeeefaaaaaaab);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expect((try a.to(u128)) == 0xefffffff00000001eeeeeeefaaaaaaab);
|
||||
}
|
||||
|
||||
test "big.int sub-limb to" {
|
||||
const a = try Int.initSet(al, 10);
|
||||
const a = try Int.initSet(testing.allocator, 10);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expect((try a.to(u8)) == 10);
|
||||
}
|
||||
|
||||
test "big.int to target too small error" {
|
||||
const a = try Int.initSet(al, 0xffffffff);
|
||||
const a = try Int.initSet(testing.allocator, 0xffffffff);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expectError(error.TargetTooSmall, a.to(u8));
|
||||
}
|
||||
|
||||
test "big.int normalize" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
try a.ensureCapacity(8);
|
||||
|
||||
a.limbs[0] = 1;
|
||||
@@ -1440,7 +1442,8 @@ test "big.int normalize" {
|
||||
}
|
||||
|
||||
test "big.int normalize multi" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
try a.ensureCapacity(8);
|
||||
|
||||
a.limbs[0] = 1;
|
||||
@@ -1469,7 +1472,9 @@ test "big.int normalize multi" {
|
||||
}
|
||||
|
||||
test "big.int parity" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.set(0);
|
||||
testing.expect(a.isEven());
|
||||
testing.expect(!a.isOdd());
|
||||
@@ -1480,7 +1485,8 @@ test "big.int parity" {
|
||||
}
|
||||
|
||||
test "big.int bitcount + sizeInBase" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.set(0b100);
|
||||
testing.expect(a.bitCountAbs() == 3);
|
||||
@@ -1507,7 +1513,8 @@ test "big.int bitcount + sizeInBase" {
|
||||
}
|
||||
|
||||
test "big.int bitcount/to" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.set(0);
|
||||
testing.expect(a.bitCountTwosComp() == 0);
|
||||
@@ -1537,7 +1544,8 @@ test "big.int bitcount/to" {
|
||||
}
|
||||
|
||||
test "big.int fits" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.set(0);
|
||||
testing.expect(a.fits(u0));
|
||||
@@ -1564,82 +1572,100 @@ test "big.int fits" {
|
||||
}
|
||||
|
||||
test "big.int string set" {
|
||||
var a = try Int.init(al);
|
||||
try a.setString(10, "120317241209124781241290847124");
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setString(10, "120317241209124781241290847124");
|
||||
testing.expect((try a.to(u128)) == 120317241209124781241290847124);
|
||||
}
|
||||
|
||||
test "big.int string negative" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setString(10, "-1023");
|
||||
testing.expect((try a.to(i32)) == -1023);
|
||||
}
|
||||
|
||||
test "big.int string set bad char error" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
testing.expectError(error.InvalidCharForDigit, a.setString(10, "x"));
|
||||
}
|
||||
|
||||
test "big.int string set bad base error" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
testing.expectError(error.InvalidBase, a.setString(45, "10"));
|
||||
}
|
||||
|
||||
test "big.int string to" {
|
||||
const a = try Int.initSet(al, 120317241209124781241290847124);
|
||||
const a = try Int.initSet(testing.allocator, 120317241209124781241290847124);
|
||||
defer a.deinit();
|
||||
|
||||
const as = try a.toString(al, 10);
|
||||
const as = try a.toString(testing.allocator, 10);
|
||||
defer testing.allocator.free(as);
|
||||
const es = "120317241209124781241290847124";
|
||||
|
||||
testing.expect(mem.eql(u8, as, es));
|
||||
}
|
||||
|
||||
test "big.int string to base base error" {
|
||||
const a = try Int.initSet(al, 0xffffffff);
|
||||
const a = try Int.initSet(testing.allocator, 0xffffffff);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expectError(error.InvalidBase, a.toString(al, 45));
|
||||
testing.expectError(error.InvalidBase, a.toString(testing.allocator, 45));
|
||||
}
|
||||
|
||||
test "big.int string to base 2" {
|
||||
const a = try Int.initSet(al, -0b1011);
|
||||
const a = try Int.initSet(testing.allocator, -0b1011);
|
||||
defer a.deinit();
|
||||
|
||||
const as = try a.toString(al, 2);
|
||||
const as = try a.toString(testing.allocator, 2);
|
||||
defer testing.allocator.free(as);
|
||||
const es = "-1011";
|
||||
|
||||
testing.expect(mem.eql(u8, as, es));
|
||||
}
|
||||
|
||||
test "big.int string to base 16" {
|
||||
const a = try Int.initSet(al, 0xefffffff00000001eeeeeeefaaaaaaab);
|
||||
const a = try Int.initSet(testing.allocator, 0xefffffff00000001eeeeeeefaaaaaaab);
|
||||
defer a.deinit();
|
||||
|
||||
const as = try a.toString(al, 16);
|
||||
const as = try a.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(as);
|
||||
const es = "efffffff00000001eeeeeeefaaaaaaab";
|
||||
|
||||
testing.expect(mem.eql(u8, as, es));
|
||||
}
|
||||
|
||||
test "big.int neg string to" {
|
||||
const a = try Int.initSet(al, -123907434);
|
||||
const a = try Int.initSet(testing.allocator, -123907434);
|
||||
defer a.deinit();
|
||||
|
||||
const as = try a.toString(al, 10);
|
||||
const as = try a.toString(testing.allocator, 10);
|
||||
defer testing.allocator.free(as);
|
||||
const es = "-123907434";
|
||||
|
||||
testing.expect(mem.eql(u8, as, es));
|
||||
}
|
||||
|
||||
test "big.int zero string to" {
|
||||
const a = try Int.initSet(al, 0);
|
||||
const a = try Int.initSet(testing.allocator, 0);
|
||||
defer a.deinit();
|
||||
|
||||
const as = try a.toString(al, 10);
|
||||
const as = try a.toString(testing.allocator, 10);
|
||||
defer testing.allocator.free(as);
|
||||
const es = "0";
|
||||
|
||||
testing.expect(mem.eql(u8, as, es));
|
||||
}
|
||||
|
||||
test "big.int clone" {
|
||||
var a = try Int.initSet(al, 1234);
|
||||
var a = try Int.initSet(testing.allocator, 1234);
|
||||
defer a.deinit();
|
||||
const b = try a.clone();
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect((try a.to(u32)) == 1234);
|
||||
testing.expect((try b.to(u32)) == 1234);
|
||||
@@ -1650,8 +1676,10 @@ test "big.int clone" {
|
||||
}
|
||||
|
||||
test "big.int swap" {
|
||||
var a = try Int.initSet(al, 1234);
|
||||
var b = try Int.initSet(al, 5678);
|
||||
var a = try Int.initSet(testing.allocator, 1234);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5678);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect((try a.to(u32)) == 1234);
|
||||
testing.expect((try b.to(u32)) == 5678);
|
||||
@@ -1663,53 +1691,65 @@ test "big.int swap" {
|
||||
}
|
||||
|
||||
test "big.int to negative" {
|
||||
var a = try Int.initSet(al, -10);
|
||||
var a = try Int.initSet(testing.allocator, -10);
|
||||
defer a.deinit();
|
||||
|
||||
testing.expect((try a.to(i32)) == -10);
|
||||
}
|
||||
|
||||
test "big.int compare" {
|
||||
var a = try Int.initSet(al, -11);
|
||||
var b = try Int.initSet(al, 10);
|
||||
var a = try Int.initSet(testing.allocator, -11);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 10);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect(a.cmpAbs(b) == 1);
|
||||
testing.expect(a.cmp(b) == -1);
|
||||
}
|
||||
|
||||
test "big.int compare similar" {
|
||||
var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);
|
||||
var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeee);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeef);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect(a.cmpAbs(b) == -1);
|
||||
testing.expect(b.cmpAbs(a) == 1);
|
||||
}
|
||||
|
||||
test "big.int compare different limb size" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, 1);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 1);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect(a.cmpAbs(b) == 1);
|
||||
testing.expect(b.cmpAbs(a) == -1);
|
||||
}
|
||||
|
||||
test "big.int compare multi-limb" {
|
||||
var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
|
||||
var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
|
||||
var a = try Int.initSet(testing.allocator, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect(a.cmpAbs(b) == 1);
|
||||
testing.expect(a.cmp(b) == -1);
|
||||
}
|
||||
|
||||
test "big.int equality" {
|
||||
var a = try Int.initSet(al, 0xffffffff1);
|
||||
var b = try Int.initSet(al, -0xffffffff1);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffff1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, -0xffffffff1);
|
||||
defer b.deinit();
|
||||
|
||||
testing.expect(a.eqAbs(b));
|
||||
testing.expect(!a.eq(b));
|
||||
}
|
||||
|
||||
test "big.int abs" {
|
||||
var a = try Int.initSet(al, -5);
|
||||
var a = try Int.initSet(testing.allocator, -5);
|
||||
defer a.deinit();
|
||||
|
||||
a.abs();
|
||||
testing.expect((try a.to(u32)) == 5);
|
||||
@@ -1719,7 +1759,8 @@ test "big.int abs" {
|
||||
}
|
||||
|
||||
test "big.int negate" {
|
||||
var a = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 5);
|
||||
defer a.deinit();
|
||||
|
||||
a.negate();
|
||||
testing.expect((try a.to(i32)) == -5);
|
||||
@@ -1729,20 +1770,26 @@ test "big.int negate" {
|
||||
}
|
||||
|
||||
test "big.int add single-single" {
|
||||
var a = try Int.initSet(al, 50);
|
||||
var b = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 50);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.add(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 55);
|
||||
}
|
||||
|
||||
test "big.int add multi-single" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, 1);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 1);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
|
||||
try c.add(a, b);
|
||||
testing.expect((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
|
||||
@@ -1754,20 +1801,26 @@ test "big.int add multi-single" {
|
||||
test "big.int add multi-multi" {
|
||||
const op1 = 0xefefefef7f7f7f7f;
|
||||
const op2 = 0xfefefefe9f9f9f9f;
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.add(a, b);
|
||||
|
||||
testing.expect((try c.to(u128)) == op1 + op2);
|
||||
}
|
||||
|
||||
test "big.int add zero-zero" {
|
||||
var a = try Int.initSet(al, 0);
|
||||
var b = try Int.initSet(al, 0);
|
||||
var a = try Int.initSet(testing.allocator, 0);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.add(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 0);
|
||||
@@ -1775,8 +1828,10 @@ test "big.int add zero-zero" {
|
||||
|
||||
test "big.int add alias multi-limb nonzero-zero" {
|
||||
const op1 = 0xffffffff777777771;
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, 0);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0);
|
||||
defer b.deinit();
|
||||
|
||||
try a.add(a, b);
|
||||
|
||||
@@ -1784,12 +1839,17 @@ test "big.int add alias multi-limb nonzero-zero" {
|
||||
}
|
||||
|
||||
test "big.int add sign" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
const one = try Int.initSet(al, 1);
|
||||
const two = try Int.initSet(al, 2);
|
||||
const neg_one = try Int.initSet(al, -1);
|
||||
const neg_two = try Int.initSet(al, -2);
|
||||
const one = try Int.initSet(testing.allocator, 1);
|
||||
defer one.deinit();
|
||||
const two = try Int.initSet(testing.allocator, 2);
|
||||
defer two.deinit();
|
||||
const neg_one = try Int.initSet(testing.allocator, -1);
|
||||
defer neg_one.deinit();
|
||||
const neg_two = try Int.initSet(testing.allocator, -2);
|
||||
defer neg_two.deinit();
|
||||
|
||||
try a.add(one, two);
|
||||
testing.expect((try a.to(i32)) == 3);
|
||||
@@ -1805,20 +1865,26 @@ test "big.int add sign" {
|
||||
}
|
||||
|
||||
test "big.int sub single-single" {
|
||||
var a = try Int.initSet(al, 50);
|
||||
var b = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 50);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.sub(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 45);
|
||||
}
|
||||
|
||||
test "big.int sub multi-single" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, 1);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 1);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.sub(a, b);
|
||||
|
||||
testing.expect((try c.to(Limb)) == maxInt(Limb));
|
||||
@@ -1828,32 +1894,43 @@ test "big.int sub multi-multi" {
|
||||
const op1 = 0xefefefefefefefefefefefef;
|
||||
const op2 = 0xabababababababababababab;
|
||||
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.sub(a, b);
|
||||
|
||||
testing.expect((try c.to(u128)) == op1 - op2);
|
||||
}
|
||||
|
||||
test "big.int sub equal" {
|
||||
var a = try Int.initSet(al, 0x11efefefefefefefefefefefef);
|
||||
var b = try Int.initSet(al, 0x11efefefefefefefefefefefef);
|
||||
var a = try Int.initSet(testing.allocator, 0x11efefefefefefefefefefefef);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x11efefefefefefefefefefefef);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.sub(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 0);
|
||||
}
|
||||
|
||||
test "big.int sub sign" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
const one = try Int.initSet(al, 1);
|
||||
const two = try Int.initSet(al, 2);
|
||||
const neg_one = try Int.initSet(al, -1);
|
||||
const neg_two = try Int.initSet(al, -2);
|
||||
const one = try Int.initSet(testing.allocator, 1);
|
||||
defer one.deinit();
|
||||
const two = try Int.initSet(testing.allocator, 2);
|
||||
defer two.deinit();
|
||||
const neg_one = try Int.initSet(testing.allocator, -1);
|
||||
defer neg_one.deinit();
|
||||
const neg_two = try Int.initSet(testing.allocator, -2);
|
||||
defer neg_two.deinit();
|
||||
|
||||
try a.sub(one, two);
|
||||
testing.expect((try a.to(i32)) == -1);
|
||||
@@ -1872,20 +1949,26 @@ test "big.int sub sign" {
|
||||
}
|
||||
|
||||
test "big.int mul single-single" {
|
||||
var a = try Int.initSet(al, 50);
|
||||
var b = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 50);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.mul(a, b);
|
||||
|
||||
testing.expect((try c.to(u64)) == 250);
|
||||
}
|
||||
|
||||
test "big.int mul multi-single" {
|
||||
var a = try Int.initSet(al, maxInt(Limb));
|
||||
var b = try Int.initSet(al, 2);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 2);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.mul(a, b);
|
||||
|
||||
testing.expect((try c.to(DoubleLimb)) == 2 * maxInt(Limb));
|
||||
@@ -1894,18 +1977,23 @@ test "big.int mul multi-single" {
|
||||
test "big.int mul multi-multi" {
|
||||
const op1 = 0x998888efefefefefefefef;
|
||||
const op2 = 0x333000abababababababab;
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.mul(a, b);
|
||||
|
||||
testing.expect((try c.to(u256)) == op1 * op2);
|
||||
}
|
||||
|
||||
test "big.int mul alias r with a" {
|
||||
var a = try Int.initSet(al, maxInt(Limb));
|
||||
var b = try Int.initSet(al, 2);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 2);
|
||||
defer b.deinit();
|
||||
|
||||
try a.mul(a, b);
|
||||
|
||||
@@ -1913,8 +2001,10 @@ test "big.int mul alias r with a" {
|
||||
}
|
||||
|
||||
test "big.int mul alias r with b" {
|
||||
var a = try Int.initSet(al, maxInt(Limb));
|
||||
var b = try Int.initSet(al, 2);
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 2);
|
||||
defer b.deinit();
|
||||
|
||||
try a.mul(b, a);
|
||||
|
||||
@@ -1922,7 +2012,8 @@ test "big.int mul alias r with b" {
|
||||
}
|
||||
|
||||
test "big.int mul alias r with a and b" {
|
||||
var a = try Int.initSet(al, maxInt(Limb));
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer a.deinit();
|
||||
|
||||
try a.mul(a, a);
|
||||
|
||||
@@ -1930,31 +2021,41 @@ test "big.int mul alias r with a and b" {
|
||||
}
|
||||
|
||||
test "big.int mul a*0" {
|
||||
var a = try Int.initSet(al, 0xefefefefefefefef);
|
||||
var b = try Int.initSet(al, 0);
|
||||
var a = try Int.initSet(testing.allocator, 0xefefefefefefefef);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.mul(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 0);
|
||||
}
|
||||
|
||||
test "big.int mul 0*0" {
|
||||
var a = try Int.initSet(al, 0);
|
||||
var b = try Int.initSet(al, 0);
|
||||
var a = try Int.initSet(testing.allocator, 0);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0);
|
||||
defer b.deinit();
|
||||
|
||||
var c = try Int.init(al);
|
||||
var c = try Int.init(testing.allocator);
|
||||
defer c.deinit();
|
||||
try c.mul(a, b);
|
||||
|
||||
testing.expect((try c.to(u32)) == 0);
|
||||
}
|
||||
|
||||
test "big.int div single-single no rem" {
|
||||
var a = try Int.initSet(al, 50);
|
||||
var b = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 50);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u32)) == 10);
|
||||
@@ -1962,11 +2063,15 @@ test "big.int div single-single no rem" {
|
||||
}
|
||||
|
||||
test "big.int div single-single with rem" {
|
||||
var a = try Int.initSet(al, 49);
|
||||
var b = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 49);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u32)) == 9);
|
||||
@@ -1977,11 +2082,15 @@ test "big.int div multi-single no rem" {
|
||||
const op1 = 0xffffeeeeddddcccc;
|
||||
const op2 = 34;
|
||||
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u64)) == op1 / op2);
|
||||
@@ -1992,11 +2101,15 @@ test "big.int div multi-single with rem" {
|
||||
const op1 = 0xffffeeeeddddcccf;
|
||||
const op2 = 34;
|
||||
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u64)) == op1 / op2);
|
||||
@@ -2007,11 +2120,15 @@ test "big.int div multi>2-single" {
|
||||
const op1 = 0xfefefefefefefefefefefefefefefefe;
|
||||
const op2 = 0xefab8;
|
||||
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == op1 / op2);
|
||||
@@ -2019,11 +2136,15 @@ test "big.int div multi>2-single" {
|
||||
}
|
||||
|
||||
test "big.int div single-single q < r" {
|
||||
var a = try Int.initSet(al, 0x0078f432);
|
||||
var b = try Int.initSet(al, 0x01000000);
|
||||
var a = try Int.initSet(testing.allocator, 0x0078f432);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x01000000);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u64)) == 0);
|
||||
@@ -2031,11 +2152,15 @@ test "big.int div single-single q < r" {
|
||||
}
|
||||
|
||||
test "big.int div single-single q == r" {
|
||||
var a = try Int.initSet(al, 10);
|
||||
var b = try Int.initSet(al, 10);
|
||||
var a = try Int.initSet(testing.allocator, 10);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 10);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u64)) == 1);
|
||||
@@ -2043,8 +2168,10 @@ test "big.int div single-single q == r" {
|
||||
}
|
||||
|
||||
test "big.int div q=0 alias" {
|
||||
var a = try Int.initSet(al, 3);
|
||||
var b = try Int.initSet(al, 10);
|
||||
var a = try Int.initSet(testing.allocator, 3);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 10);
|
||||
defer b.deinit();
|
||||
|
||||
try Int.divTrunc(&a, &b, a, b);
|
||||
|
||||
@@ -2055,11 +2182,15 @@ test "big.int div q=0 alias" {
|
||||
test "big.int div multi-multi q < r" {
|
||||
const op1 = 0x1ffffffff0078f432;
|
||||
const op2 = 0x1ffffffff01000000;
|
||||
var a = try Int.initSet(al, op1);
|
||||
var b = try Int.initSet(al, op2);
|
||||
var a = try Int.initSet(testing.allocator, op1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, op2);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0);
|
||||
@@ -2070,11 +2201,15 @@ test "big.int div trunc single-single +/+" {
|
||||
const u: i32 = 5;
|
||||
const v: i32 = 3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2090,11 +2225,15 @@ test "big.int div trunc single-single -/+" {
|
||||
const u: i32 = -5;
|
||||
const v: i32 = 3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2110,11 +2249,15 @@ test "big.int div trunc single-single +/-" {
|
||||
const u: i32 = 5;
|
||||
const v: i32 = -3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2130,11 +2273,15 @@ test "big.int div trunc single-single -/-" {
|
||||
const u: i32 = -5;
|
||||
const v: i32 = -3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2150,11 +2297,15 @@ test "big.int div floor single-single +/+" {
|
||||
const u: i32 = 5;
|
||||
const v: i32 = 3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divFloor(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2170,11 +2321,15 @@ test "big.int div floor single-single -/+" {
|
||||
const u: i32 = -5;
|
||||
const v: i32 = 3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divFloor(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2190,11 +2345,15 @@ test "big.int div floor single-single +/-" {
|
||||
const u: i32 = 5;
|
||||
const v: i32 = -3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divFloor(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2210,11 +2369,15 @@ test "big.int div floor single-single -/-" {
|
||||
const u: i32 = -5;
|
||||
const v: i32 = -3;
|
||||
|
||||
var a = try Int.initSet(al, u);
|
||||
var b = try Int.initSet(al, v);
|
||||
var a = try Int.initSet(testing.allocator, u);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, v);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divFloor(&q, &r, a, b);
|
||||
|
||||
// n = q * d + r
|
||||
@@ -2227,11 +2390,15 @@ test "big.int div floor single-single -/-" {
|
||||
}
|
||||
|
||||
test "big.int div multi-multi with rem" {
|
||||
var a = try Int.initSet(al, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
|
||||
var b = try Int.initSet(al, 0x99990000111122223333);
|
||||
var a = try Int.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x99990000111122223333);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
|
||||
@@ -2239,11 +2406,15 @@ test "big.int div multi-multi with rem" {
|
||||
}
|
||||
|
||||
test "big.int div multi-multi no rem" {
|
||||
var a = try Int.initSet(al, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
|
||||
var b = try Int.initSet(al, 0x99990000111122223333);
|
||||
var a = try Int.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x99990000111122223333);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
|
||||
@@ -2251,11 +2422,15 @@ test "big.int div multi-multi no rem" {
|
||||
}
|
||||
|
||||
test "big.int div multi-multi (2 branch)" {
|
||||
var a = try Int.initSet(al, 0x866666665555555588888887777777761111111111111111);
|
||||
var b = try Int.initSet(al, 0x86666666555555554444444433333333);
|
||||
var a = try Int.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x86666666555555554444444433333333);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0x10000000000000000);
|
||||
@@ -2263,11 +2438,15 @@ test "big.int div multi-multi (2 branch)" {
|
||||
}
|
||||
|
||||
test "big.int div multi-multi (3.1/3.3 branch)" {
|
||||
var a = try Int.initSet(al, 0x11111111111111111111111111111111111111111111111111111111111111);
|
||||
var b = try Int.initSet(al, 0x1111111111111111111111111111111111111111171);
|
||||
var a = try Int.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0xfffffffffffffffffff);
|
||||
@@ -2275,145 +2454,189 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
|
||||
}
|
||||
|
||||
test "big.int div multi-single zero-limb trailing" {
|
||||
var a = try Int.initSet(al, 0x60000000000000000000000000000000000000000000000000000000000000000);
|
||||
var b = try Int.initSet(al, 0x10000000000000000);
|
||||
var a = try Int.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x10000000000000000);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
var expected = try Int.initSet(al, 0x6000000000000000000000000000000000000000000000000);
|
||||
var expected = try Int.initSet(testing.allocator, 0x6000000000000000000000000000000000000000000000000);
|
||||
defer expected.deinit();
|
||||
testing.expect(q.eq(expected));
|
||||
testing.expect(r.eqZero());
|
||||
}
|
||||
|
||||
test "big.int div multi-multi zero-limb trailing (with rem)" {
|
||||
var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
||||
var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
||||
var a = try Int.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0x10000000000000000);
|
||||
|
||||
const rs = try r.toString(al, 16);
|
||||
const rs = try r.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(rs);
|
||||
testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000"));
|
||||
}
|
||||
|
||||
test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
|
||||
var a = try Int.initSet(al, 0x8666666655555555888888877777777611111111111111110000000000000000);
|
||||
var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
||||
var a = try Int.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
testing.expect((try q.to(u128)) == 0x1);
|
||||
|
||||
const rs = try r.toString(al, 16);
|
||||
const rs = try r.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(rs);
|
||||
testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000"));
|
||||
}
|
||||
|
||||
test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
|
||||
var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
||||
var b = try Int.initSet(al, 0x866666665555555544444444333333330000000000000000);
|
||||
var a = try Int.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
|
||||
defer b.deinit();
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
const qs = try q.toString(al, 16);
|
||||
const qs = try q.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(qs);
|
||||
testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f"));
|
||||
|
||||
const rs = try r.toString(al, 16);
|
||||
const rs = try r.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(rs);
|
||||
testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000"));
|
||||
}
|
||||
|
||||
test "big.int div multi-multi fuzz case #1" {
|
||||
var a = try Int.init(al);
|
||||
var b = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Int.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
try a.setString(16, "ffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
try b.setString(16, "3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000000000000000000007fffffffffff");
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
const qs = try q.toString(al, 16);
|
||||
const qs = try q.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(qs);
|
||||
testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1"));
|
||||
|
||||
const rs = try r.toString(al, 16);
|
||||
const rs = try r.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(rs);
|
||||
testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1"));
|
||||
}
|
||||
|
||||
test "big.int div multi-multi fuzz case #2" {
|
||||
var a = try Int.init(al);
|
||||
var b = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Int.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
try a.setString(16, "3ffffffffe00000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000001fffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffc000000000000000000000000000000000000000000000000000000000000000");
|
||||
try b.setString(16, "ffc0000000000000000000000000000000000000000000000000");
|
||||
|
||||
var q = try Int.init(al);
|
||||
var r = try Int.init(al);
|
||||
var q = try Int.init(testing.allocator);
|
||||
defer q.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
try Int.divTrunc(&q, &r, a, b);
|
||||
|
||||
const qs = try q.toString(al, 16);
|
||||
const qs = try q.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(qs);
|
||||
testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4"));
|
||||
|
||||
const rs = try r.toString(al, 16);
|
||||
const rs = try r.toString(testing.allocator, 16);
|
||||
defer testing.allocator.free(rs);
|
||||
testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000"));
|
||||
}
|
||||
|
||||
test "big.int shift-right single" {
|
||||
var a = try Int.initSet(al, 0xffff0000);
|
||||
var a = try Int.initSet(testing.allocator, 0xffff0000);
|
||||
defer a.deinit();
|
||||
try a.shiftRight(a, 16);
|
||||
|
||||
testing.expect((try a.to(u32)) == 0xffff);
|
||||
}
|
||||
|
||||
test "big.int shift-right multi" {
|
||||
var a = try Int.initSet(al, 0xffff0000eeee1111dddd2222cccc3333);
|
||||
var a = try Int.initSet(testing.allocator, 0xffff0000eeee1111dddd2222cccc3333);
|
||||
defer a.deinit();
|
||||
try a.shiftRight(a, 67);
|
||||
|
||||
testing.expect((try a.to(u64)) == 0x1fffe0001dddc222);
|
||||
}
|
||||
|
||||
test "big.int shift-left single" {
|
||||
var a = try Int.initSet(al, 0xffff);
|
||||
var a = try Int.initSet(testing.allocator, 0xffff);
|
||||
defer a.deinit();
|
||||
try a.shiftLeft(a, 16);
|
||||
|
||||
testing.expect((try a.to(u64)) == 0xffff0000);
|
||||
}
|
||||
|
||||
test "big.int shift-left multi" {
|
||||
var a = try Int.initSet(al, 0x1fffe0001dddc222);
|
||||
var a = try Int.initSet(testing.allocator, 0x1fffe0001dddc222);
|
||||
defer a.deinit();
|
||||
try a.shiftLeft(a, 67);
|
||||
|
||||
testing.expect((try a.to(u128)) == 0xffff0000eeee11100000000000000000);
|
||||
}
|
||||
|
||||
test "big.int shift-right negative" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.shiftRight(try Int.initSet(al, -20), 2);
|
||||
try a.shiftRight(try Int.initSet(testing.allocator, -20), 2);
|
||||
defer a.deinit();
|
||||
testing.expect((try a.to(i32)) == -20 >> 2);
|
||||
|
||||
try a.shiftRight(try Int.initSet(al, -5), 10);
|
||||
try a.shiftRight(try Int.initSet(testing.allocator, -5), 10);
|
||||
defer a.deinit();
|
||||
testing.expect((try a.to(i32)) == -5 >> 10);
|
||||
}
|
||||
|
||||
test "big.int shift-left negative" {
|
||||
var a = try Int.init(al);
|
||||
var a = try Int.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.shiftRight(try Int.initSet(al, -10), 1232);
|
||||
try a.shiftRight(try Int.initSet(testing.allocator, -10), 1232);
|
||||
defer a.deinit();
|
||||
testing.expect((try a.to(i32)) == -10 >> 1232);
|
||||
}
|
||||
|
||||
test "big.int bitwise and simple" {
|
||||
var a = try Int.initSet(al, 0xffffffff11111111);
|
||||
var b = try Int.initSet(al, 0xeeeeeeee22222222);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffff11111111);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0xeeeeeeee22222222);
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitAnd(a, b);
|
||||
|
||||
@@ -2421,8 +2644,10 @@ test "big.int bitwise and simple" {
|
||||
}
|
||||
|
||||
test "big.int bitwise and multi-limb" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, maxInt(Limb));
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitAnd(a, b);
|
||||
|
||||
@@ -2430,8 +2655,10 @@ test "big.int bitwise and multi-limb" {
|
||||
}
|
||||
|
||||
test "big.int bitwise xor simple" {
|
||||
var a = try Int.initSet(al, 0xffffffff11111111);
|
||||
var b = try Int.initSet(al, 0xeeeeeeee22222222);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffff11111111);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0xeeeeeeee22222222);
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitXor(a, b);
|
||||
|
||||
@@ -2439,8 +2666,10 @@ test "big.int bitwise xor simple" {
|
||||
}
|
||||
|
||||
test "big.int bitwise xor multi-limb" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, maxInt(Limb));
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitXor(a, b);
|
||||
|
||||
@@ -2448,8 +2677,10 @@ test "big.int bitwise xor multi-limb" {
|
||||
}
|
||||
|
||||
test "big.int bitwise or simple" {
|
||||
var a = try Int.initSet(al, 0xffffffff11111111);
|
||||
var b = try Int.initSet(al, 0xeeeeeeee22222222);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffff11111111);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0xeeeeeeee22222222);
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitOr(a, b);
|
||||
|
||||
@@ -2457,8 +2688,10 @@ test "big.int bitwise or simple" {
|
||||
}
|
||||
|
||||
test "big.int bitwise or multi-limb" {
|
||||
var a = try Int.initSet(al, maxInt(Limb) + 1);
|
||||
var b = try Int.initSet(al, maxInt(Limb));
|
||||
var a = try Int.initSet(testing.allocator, maxInt(Limb) + 1);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, maxInt(Limb));
|
||||
defer b.deinit();
|
||||
|
||||
try a.bitOr(a, b);
|
||||
|
||||
@@ -2467,11 +2700,19 @@ test "big.int bitwise or multi-limb" {
|
||||
}
|
||||
|
||||
test "big.int var args" {
|
||||
var a = try Int.initSet(al, 5);
|
||||
var a = try Int.initSet(testing.allocator, 5);
|
||||
defer a.deinit();
|
||||
|
||||
try a.add(a, try Int.initSet(al, 6));
|
||||
const b = try Int.initSet(testing.allocator, 6);
|
||||
defer b.deinit();
|
||||
try a.add(a, b);
|
||||
testing.expect((try a.to(u64)) == 11);
|
||||
|
||||
testing.expect(a.cmp(try Int.initSet(al, 11)) == 0);
|
||||
testing.expect(a.cmp(try Int.initSet(al, 14)) <= 0);
|
||||
const c = try Int.initSet(testing.allocator, 11);
|
||||
defer c.deinit();
|
||||
testing.expect(a.cmp(c) == 0);
|
||||
|
||||
const d = try Int.initSet(testing.allocator, 14);
|
||||
defer d.deinit();
|
||||
testing.expect(a.cmp(d) <= 0);
|
||||
}
|
||||
|
||||
@@ -587,14 +587,13 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void {
|
||||
r.swap(&x);
|
||||
}
|
||||
|
||||
var buffer: [64 * 8192]u8 = undefined;
|
||||
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
|
||||
var al = &fixed.allocator;
|
||||
|
||||
test "big.rational gcd non-one small" {
|
||||
var a = try Int.initSet(al, 17);
|
||||
var b = try Int.initSet(al, 97);
|
||||
var r = try Int.init(al);
|
||||
var a = try Int.initSet(testing.allocator, 17);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 97);
|
||||
defer b.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try gcd(&r, a, b);
|
||||
|
||||
@@ -602,9 +601,12 @@ test "big.rational gcd non-one small" {
|
||||
}
|
||||
|
||||
test "big.rational gcd non-one small" {
|
||||
var a = try Int.initSet(al, 4864);
|
||||
var b = try Int.initSet(al, 3458);
|
||||
var r = try Int.init(al);
|
||||
var a = try Int.initSet(testing.allocator, 4864);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 3458);
|
||||
defer b.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try gcd(&r, a, b);
|
||||
|
||||
@@ -612,9 +614,12 @@ test "big.rational gcd non-one small" {
|
||||
}
|
||||
|
||||
test "big.rational gcd non-one large" {
|
||||
var a = try Int.initSet(al, 0xffffffffffffffff);
|
||||
var b = try Int.initSet(al, 0xffffffffffffffff7777);
|
||||
var r = try Int.init(al);
|
||||
var a = try Int.initSet(testing.allocator, 0xffffffffffffffff);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0xffffffffffffffff7777);
|
||||
defer b.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try gcd(&r, a, b);
|
||||
|
||||
@@ -622,9 +627,12 @@ test "big.rational gcd non-one large" {
|
||||
}
|
||||
|
||||
test "big.rational gcd large multi-limb result" {
|
||||
var a = try Int.initSet(al, 0x12345678123456781234567812345678123456781234567812345678);
|
||||
var b = try Int.initSet(al, 0x12345671234567123456712345671234567123456712345671234567);
|
||||
var r = try Int.init(al);
|
||||
var a = try Int.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
|
||||
defer b.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try gcd(&r, a, b);
|
||||
|
||||
@@ -632,9 +640,12 @@ test "big.rational gcd large multi-limb result" {
|
||||
}
|
||||
|
||||
test "big.rational gcd one large" {
|
||||
var a = try Int.initSet(al, 1897056385327307);
|
||||
var b = try Int.initSet(al, 2251799813685248);
|
||||
var r = try Int.init(al);
|
||||
var a = try Int.initSet(testing.allocator, 1897056385327307);
|
||||
defer a.deinit();
|
||||
var b = try Int.initSet(testing.allocator, 2251799813685248);
|
||||
defer b.deinit();
|
||||
var r = try Int.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try gcd(&r, a, b);
|
||||
|
||||
@@ -661,7 +672,8 @@ fn extractLowBits(a: Int, comptime T: type) T {
|
||||
}
|
||||
|
||||
test "big.rational extractLowBits" {
|
||||
var a = try Int.initSet(al, 0x11112222333344441234567887654321);
|
||||
var a = try Int.initSet(testing.allocator, 0x11112222333344441234567887654321);
|
||||
defer a.deinit();
|
||||
|
||||
const a1 = extractLowBits(a, u8);
|
||||
testing.expect(a1 == 0x21);
|
||||
@@ -680,7 +692,8 @@ test "big.rational extractLowBits" {
|
||||
}
|
||||
|
||||
test "big.rational set" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setInt(5);
|
||||
testing.expect((try a.p.to(u32)) == 5);
|
||||
@@ -708,7 +721,8 @@ test "big.rational set" {
|
||||
}
|
||||
|
||||
test "big.rational setFloat" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setFloat(f64, 2.5);
|
||||
testing.expect((try a.p.to(i32)) == 5);
|
||||
@@ -732,7 +746,8 @@ test "big.rational setFloat" {
|
||||
}
|
||||
|
||||
test "big.rational setFloatString" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setFloatString("72.14159312071241458852455252781510353");
|
||||
|
||||
@@ -742,7 +757,8 @@ test "big.rational setFloatString" {
|
||||
}
|
||||
|
||||
test "big.rational toFloat" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
// = 3.14159297943115234375
|
||||
try a.setRatio(3294199, 1048576);
|
||||
@@ -754,7 +770,8 @@ test "big.rational toFloat" {
|
||||
}
|
||||
|
||||
test "big.rational set/to Float round-trip" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var prng = std.rand.DefaultPrng.init(0x5EED);
|
||||
var i: usize = 0;
|
||||
while (i < 512) : (i += 1) {
|
||||
@@ -765,23 +782,29 @@ test "big.rational set/to Float round-trip" {
|
||||
}
|
||||
|
||||
test "big.rational copy" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
const b = try Int.initSet(al, 5);
|
||||
const b = try Int.initSet(testing.allocator, 5);
|
||||
defer b.deinit();
|
||||
|
||||
try a.copyInt(b);
|
||||
testing.expect((try a.p.to(u32)) == 5);
|
||||
testing.expect((try a.q.to(u32)) == 1);
|
||||
|
||||
const c = try Int.initSet(al, 7);
|
||||
const d = try Int.initSet(al, 3);
|
||||
const c = try Int.initSet(testing.allocator, 7);
|
||||
defer c.deinit();
|
||||
const d = try Int.initSet(testing.allocator, 3);
|
||||
defer d.deinit();
|
||||
|
||||
try a.copyRatio(c, d);
|
||||
testing.expect((try a.p.to(u32)) == 7);
|
||||
testing.expect((try a.q.to(u32)) == 3);
|
||||
|
||||
const e = try Int.initSet(al, 9);
|
||||
const f = try Int.initSet(al, 3);
|
||||
const e = try Int.initSet(testing.allocator, 9);
|
||||
defer e.deinit();
|
||||
const f = try Int.initSet(testing.allocator, 3);
|
||||
defer f.deinit();
|
||||
|
||||
try a.copyRatio(e, f);
|
||||
testing.expect((try a.p.to(u32)) == 3);
|
||||
@@ -789,7 +812,8 @@ test "big.rational copy" {
|
||||
}
|
||||
|
||||
test "big.rational negate" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setInt(-50);
|
||||
testing.expect((try a.p.to(i32)) == -50);
|
||||
@@ -805,7 +829,8 @@ test "big.rational negate" {
|
||||
}
|
||||
|
||||
test "big.rational abs" {
|
||||
var a = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
try a.setInt(-50);
|
||||
testing.expect((try a.p.to(i32)) == -50);
|
||||
@@ -821,8 +846,10 @@ test "big.rational abs" {
|
||||
}
|
||||
|
||||
test "big.rational swap" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
try a.setRatio(50, 23);
|
||||
try b.setRatio(17, 3);
|
||||
@@ -843,8 +870,10 @@ test "big.rational swap" {
|
||||
}
|
||||
|
||||
test "big.rational cmp" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
try a.setRatio(500, 231);
|
||||
try b.setRatio(18903, 8584);
|
||||
@@ -856,8 +885,10 @@ test "big.rational cmp" {
|
||||
}
|
||||
|
||||
test "big.rational add single-limb" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
|
||||
try a.setRatio(500, 231);
|
||||
try b.setRatio(18903, 8584);
|
||||
@@ -869,9 +900,12 @@ test "big.rational add single-limb" {
|
||||
}
|
||||
|
||||
test "big.rational add" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var r = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
@@ -882,9 +916,12 @@ test "big.rational add" {
|
||||
}
|
||||
|
||||
test "big.rational sub" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var r = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
@@ -895,9 +932,12 @@ test "big.rational sub" {
|
||||
}
|
||||
|
||||
test "big.rational mul" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var r = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
@@ -908,9 +948,12 @@ test "big.rational mul" {
|
||||
}
|
||||
|
||||
test "big.rational div" {
|
||||
var a = try Rational.init(al);
|
||||
var b = try Rational.init(al);
|
||||
var r = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
@@ -921,8 +964,10 @@ test "big.rational div" {
|
||||
}
|
||||
|
||||
test "big.rational div" {
|
||||
var a = try Rational.init(al);
|
||||
var r = try Rational.init(al);
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
a.invert();
|
||||
|
||||
+30
-14
@@ -1011,11 +1011,21 @@ pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []cons
|
||||
}
|
||||
|
||||
test "mem.join" {
|
||||
var buf: [1024]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
testing.expect(eql(u8, try join(a, ",", &[_][]const u8{ "a", "b", "c" }), "a,b,c"));
|
||||
testing.expect(eql(u8, try join(a, ",", &[_][]const u8{"a"}), "a"));
|
||||
testing.expect(eql(u8, try join(a, ",", &[_][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c"));
|
||||
{
|
||||
const str = try join(testing.allocator, ",", &[_][]const u8{ "a", "b", "c" });
|
||||
defer testing.allocator.free(str);
|
||||
testing.expect(eql(u8, str, "a,b,c"));
|
||||
}
|
||||
{
|
||||
const str = try join(testing.allocator, ",", &[_][]const u8{"a"});
|
||||
defer testing.allocator.free(str);
|
||||
testing.expect(eql(u8, str, "a"));
|
||||
}
|
||||
{
|
||||
const str = try join(testing.allocator, ",", &[_][]const u8{ "a", "", "b", "", "c" });
|
||||
defer testing.allocator.free(str);
|
||||
testing.expect(eql(u8, str, "a,,b,,c"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies each T from slices into a new slice that exactly holds all the elements.
|
||||
@@ -1044,15 +1054,21 @@ pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T
|
||||
}
|
||||
|
||||
test "concat" {
|
||||
var buf: [1024]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
testing.expect(eql(u8, try concat(a, u8, &[_][]const u8{ "abc", "def", "ghi" }), "abcdefghi"));
|
||||
testing.expect(eql(u32, try concat(a, u32, &[_][]const u32{
|
||||
&[_]u32{ 0, 1 },
|
||||
&[_]u32{ 2, 3, 4 },
|
||||
&[_]u32{},
|
||||
&[_]u32{5},
|
||||
}), &[_]u32{ 0, 1, 2, 3, 4, 5 }));
|
||||
{
|
||||
const str = try concat(testing.allocator, u8, &[_][]const u8{ "abc", "def", "ghi" });
|
||||
defer testing.allocator.free(str);
|
||||
testing.expect(eql(u8, str, "abcdefghi"));
|
||||
}
|
||||
{
|
||||
const str = try concat(testing.allocator, u32, &[_][]const u32{
|
||||
&[_]u32{ 0, 1 },
|
||||
&[_]u32{ 2, 3, 4 },
|
||||
&[_]u32{},
|
||||
&[_]u32{5},
|
||||
});
|
||||
defer testing.allocator.free(str);
|
||||
testing.expect(eql(u32, str, &[_]u32{ 0, 1, 2, 3, 4, 5 }));
|
||||
}
|
||||
}
|
||||
|
||||
test "testStringEquality" {
|
||||
|
||||
+64
-59
@@ -7,13 +7,12 @@ const testing = std.testing;
|
||||
|
||||
pub const trait = @import("meta/trait.zig");
|
||||
|
||||
const TypeId = builtin.TypeId;
|
||||
const TypeInfo = builtin.TypeInfo;
|
||||
|
||||
pub fn tagName(v: var) []const u8 {
|
||||
const T = @TypeOf(v);
|
||||
switch (@typeInfo(T)) {
|
||||
TypeId.ErrorSet => return @errorName(v),
|
||||
.ErrorSet => return @errorName(v),
|
||||
else => return @tagName(v),
|
||||
}
|
||||
}
|
||||
@@ -55,7 +54,7 @@ test "std.meta.tagName" {
|
||||
|
||||
pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
|
||||
inline for (@typeInfo(T).Enum.fields) |enumField| {
|
||||
if (std.mem.eql(u8, str, enumField.name)) {
|
||||
if (mem.eql(u8, str, enumField.name)) {
|
||||
return @field(T, enumField.name);
|
||||
}
|
||||
}
|
||||
@@ -74,9 +73,9 @@ test "std.meta.stringToEnum" {
|
||||
|
||||
pub fn bitCount(comptime T: type) comptime_int {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Bool => 1,
|
||||
TypeId.Int => |info| info.bits,
|
||||
TypeId.Float => |info| info.bits,
|
||||
.Bool => 1,
|
||||
.Int => |info| info.bits,
|
||||
.Float => |info| info.bits,
|
||||
else => @compileError("Expected bool, int or float type, found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -88,7 +87,7 @@ test "std.meta.bitCount" {
|
||||
|
||||
pub fn alignment(comptime T: type) comptime_int {
|
||||
//@alignOf works on non-pointer types
|
||||
const P = if (comptime trait.is(TypeId.Pointer)(T)) T else *T;
|
||||
const P = if (comptime trait.is(.Pointer)(T)) T else *T;
|
||||
return @typeInfo(P).Pointer.alignment;
|
||||
}
|
||||
|
||||
@@ -102,9 +101,9 @@ test "std.meta.alignment" {
|
||||
|
||||
pub fn Child(comptime T: type) type {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Array => |info| info.child,
|
||||
TypeId.Pointer => |info| info.child,
|
||||
TypeId.Optional => |info| info.child,
|
||||
.Array => |info| info.child,
|
||||
.Pointer => |info| info.child,
|
||||
.Optional => |info| info.child,
|
||||
else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -118,9 +117,9 @@ test "std.meta.Child" {
|
||||
|
||||
pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Struct => |info| info.layout,
|
||||
TypeId.Enum => |info| info.layout,
|
||||
TypeId.Union => |info| info.layout,
|
||||
.Struct => |info| info.layout,
|
||||
.Enum => |info| info.layout,
|
||||
.Union => |info| info.layout,
|
||||
else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -148,22 +147,22 @@ test "std.meta.containerLayout" {
|
||||
a: u8,
|
||||
};
|
||||
|
||||
testing.expect(containerLayout(E1) == TypeInfo.ContainerLayout.Auto);
|
||||
testing.expect(containerLayout(E2) == TypeInfo.ContainerLayout.Packed);
|
||||
testing.expect(containerLayout(E3) == TypeInfo.ContainerLayout.Extern);
|
||||
testing.expect(containerLayout(S1) == TypeInfo.ContainerLayout.Auto);
|
||||
testing.expect(containerLayout(S2) == TypeInfo.ContainerLayout.Packed);
|
||||
testing.expect(containerLayout(S3) == TypeInfo.ContainerLayout.Extern);
|
||||
testing.expect(containerLayout(U1) == TypeInfo.ContainerLayout.Auto);
|
||||
testing.expect(containerLayout(U2) == TypeInfo.ContainerLayout.Packed);
|
||||
testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
|
||||
testing.expect(containerLayout(E1) == .Auto);
|
||||
testing.expect(containerLayout(E2) == .Packed);
|
||||
testing.expect(containerLayout(E3) == .Extern);
|
||||
testing.expect(containerLayout(S1) == .Auto);
|
||||
testing.expect(containerLayout(S2) == .Packed);
|
||||
testing.expect(containerLayout(S3) == .Extern);
|
||||
testing.expect(containerLayout(U1) == .Auto);
|
||||
testing.expect(containerLayout(U2) == .Packed);
|
||||
testing.expect(containerLayout(U3) == .Extern);
|
||||
}
|
||||
|
||||
pub fn declarations(comptime T: type) []TypeInfo.Declaration {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Struct => |info| info.decls,
|
||||
TypeId.Enum => |info| info.decls,
|
||||
TypeId.Union => |info| info.decls,
|
||||
.Struct => |info| info.decls,
|
||||
.Enum => |info| info.decls,
|
||||
.Union => |info| info.decls,
|
||||
else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -232,17 +231,17 @@ test "std.meta.declarationInfo" {
|
||||
}
|
||||
|
||||
pub fn fields(comptime T: type) switch (@typeInfo(T)) {
|
||||
TypeId.Struct => []TypeInfo.StructField,
|
||||
TypeId.Union => []TypeInfo.UnionField,
|
||||
TypeId.ErrorSet => []TypeInfo.Error,
|
||||
TypeId.Enum => []TypeInfo.EnumField,
|
||||
.Struct => []TypeInfo.StructField,
|
||||
.Union => []TypeInfo.UnionField,
|
||||
.ErrorSet => []TypeInfo.Error,
|
||||
.Enum => []TypeInfo.EnumField,
|
||||
else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
|
||||
} {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Struct => |info| info.fields,
|
||||
TypeId.Union => |info| info.fields,
|
||||
TypeId.Enum => |info| info.fields,
|
||||
TypeId.ErrorSet => |errors| errors.?, // must be non global error set
|
||||
.Struct => |info| info.fields,
|
||||
.Union => |info| info.fields,
|
||||
.Enum => |info| info.fields,
|
||||
.ErrorSet => |errors| errors.?, // must be non global error set
|
||||
else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -277,10 +276,10 @@ test "std.meta.fields" {
|
||||
}
|
||||
|
||||
pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typeInfo(T)) {
|
||||
TypeId.Struct => TypeInfo.StructField,
|
||||
TypeId.Union => TypeInfo.UnionField,
|
||||
TypeId.ErrorSet => TypeInfo.Error,
|
||||
TypeId.Enum => TypeInfo.EnumField,
|
||||
.Struct => TypeInfo.StructField,
|
||||
.Union => TypeInfo.UnionField,
|
||||
.ErrorSet => TypeInfo.Error,
|
||||
.Enum => TypeInfo.EnumField,
|
||||
else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
|
||||
} {
|
||||
inline for (comptime fields(T)) |field| {
|
||||
@@ -318,8 +317,8 @@ test "std.meta.fieldInfo" {
|
||||
|
||||
pub fn TagType(comptime T: type) type {
|
||||
return switch (@typeInfo(T)) {
|
||||
TypeId.Enum => |info| info.tag_type,
|
||||
TypeId.Union => |info| if (info.tag_type) |Tag| Tag else null,
|
||||
.Enum => |info| info.tag_type,
|
||||
.Union => |info| if (info.tag_type) |Tag| Tag else null,
|
||||
else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
@@ -365,7 +364,7 @@ test "std.meta.activeTag" {
|
||||
///Given a tagged union type, and an enum, return the type of the union
|
||||
/// field corresponding to the enum tag.
|
||||
pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type {
|
||||
testing.expect(trait.is(builtin.TypeId.Union)(U));
|
||||
testing.expect(trait.is(.Union)(U));
|
||||
|
||||
const info = @typeInfo(U).Union;
|
||||
|
||||
@@ -387,30 +386,26 @@ test "std.meta.TagPayloadType" {
|
||||
testing.expect(MovedEvent == @TypeOf(e.Moved));
|
||||
}
|
||||
|
||||
///Compares two of any type for equality. Containers are compared on a field-by-field basis,
|
||||
/// Compares two of any type for equality. Containers are compared on a field-by-field basis,
|
||||
/// where possible. Pointers are not followed.
|
||||
pub fn eql(a: var, b: @TypeOf(a)) bool {
|
||||
const T = @TypeOf(a);
|
||||
|
||||
switch (@typeId(T)) {
|
||||
builtin.TypeId.Struct => {
|
||||
const info = @typeInfo(T).Struct;
|
||||
|
||||
switch (@typeInfo(T)) {
|
||||
.Struct => |info| {
|
||||
inline for (info.fields) |field_info| {
|
||||
if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
builtin.TypeId.ErrorUnion => {
|
||||
.ErrorUnion => {
|
||||
if (a) |a_p| {
|
||||
if (b) |b_p| return eql(a_p, b_p) else |_| return false;
|
||||
} else |a_e| {
|
||||
if (b) |_| return false else |b_e| return a_e == b_e;
|
||||
}
|
||||
},
|
||||
builtin.TypeId.Union => {
|
||||
const info = @typeInfo(T).Union;
|
||||
|
||||
.Union => |info| {
|
||||
if (info.tag_type) |_| {
|
||||
const tag_a = activeTag(a);
|
||||
const tag_b = activeTag(b);
|
||||
@@ -427,23 +422,26 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {
|
||||
|
||||
@compileError("cannot compare untagged union type " ++ @typeName(T));
|
||||
},
|
||||
builtin.TypeId.Array => {
|
||||
.Array => {
|
||||
if (a.len != b.len) return false;
|
||||
for (a) |e, i|
|
||||
if (!eql(e, b[i])) return false;
|
||||
return true;
|
||||
},
|
||||
builtin.TypeId.Pointer => {
|
||||
const info = @typeInfo(T).Pointer;
|
||||
switch (info.size) {
|
||||
builtin.TypeInfo.Pointer.Size.One,
|
||||
builtin.TypeInfo.Pointer.Size.Many,
|
||||
builtin.TypeInfo.Pointer.Size.C,
|
||||
=> return a == b,
|
||||
builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len,
|
||||
.Vector => |info| {
|
||||
var i: usize = 0;
|
||||
while (i < info.len) : (i += 1) {
|
||||
if (!eql(a[i], b[i])) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
builtin.TypeId.Optional => {
|
||||
.Pointer => |info| {
|
||||
return switch (info.size) {
|
||||
.One, .Many, .C, => a == b,
|
||||
.Slice => a.ptr == b.ptr and a.len == b.len,
|
||||
};
|
||||
},
|
||||
.Optional => {
|
||||
if (a == null and b == null) return true;
|
||||
if (a == null or b == null) return false;
|
||||
return eql(a.?, b.?);
|
||||
@@ -510,6 +508,13 @@ test "std.meta.eql" {
|
||||
testing.expect(eql(EU.tst(true), EU.tst(true)));
|
||||
testing.expect(eql(EU.tst(false), EU.tst(false)));
|
||||
testing.expect(!eql(EU.tst(false), EU.tst(true)));
|
||||
|
||||
var v1 = @splat(4, @as(u32, 1));
|
||||
var v2 = @splat(4, @as(u32, 1));
|
||||
var v3 = @splat(4, @as(u32, 2));
|
||||
|
||||
testing.expect(eql(v1, v2));
|
||||
testing.expect(!eql(v1, v3));
|
||||
}
|
||||
|
||||
test "intToEnum with error return" {
|
||||
|
||||
+43
-64
@@ -7,17 +7,11 @@ const warn = debug.warn;
|
||||
|
||||
const meta = @import("../meta.zig");
|
||||
|
||||
//This is necessary if we want to return generic functions directly because of how the
|
||||
// the type erasure works. see: #1375
|
||||
fn traitFnWorkaround(comptime T: type) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub const TraitFn = @TypeOf(traitFnWorkaround);
|
||||
pub const TraitFn = fn (type) bool;
|
||||
|
||||
//////Trait generators
|
||||
|
||||
//Need TraitList because compiler can't do varargs at comptime yet
|
||||
// TODO convert to tuples when #4335 is done
|
||||
pub const TraitList = []const TraitFn;
|
||||
pub fn multiTrait(comptime traits: TraitList) TraitFn {
|
||||
const Closure = struct {
|
||||
@@ -60,8 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {
|
||||
if (!comptime isContainer(T)) return false;
|
||||
if (!comptime @hasDecl(T, name)) return false;
|
||||
const DeclType = @TypeOf(@field(T, name));
|
||||
const decl_type_id = @typeId(DeclType);
|
||||
return decl_type_id == builtin.TypeId.Fn;
|
||||
return @typeId(DeclType) == .Fn;
|
||||
}
|
||||
};
|
||||
return Closure.trait;
|
||||
@@ -80,11 +73,10 @@ test "std.meta.trait.hasFn" {
|
||||
pub fn hasField(comptime name: []const u8) TraitFn {
|
||||
const Closure = struct {
|
||||
pub fn trait(comptime T: type) bool {
|
||||
const info = @typeInfo(T);
|
||||
const fields = switch (info) {
|
||||
builtin.TypeId.Struct => |s| s.fields,
|
||||
builtin.TypeId.Union => |u| u.fields,
|
||||
builtin.TypeId.Enum => |e| e.fields,
|
||||
const fields = switch (@typeInfo(T)) {
|
||||
.Struct => |s| s.fields,
|
||||
.Union => |u| u.fields,
|
||||
.Enum => |e| e.fields,
|
||||
else => return false,
|
||||
};
|
||||
|
||||
@@ -120,11 +112,11 @@ pub fn is(comptime id: builtin.TypeId) TraitFn {
|
||||
}
|
||||
|
||||
test "std.meta.trait.is" {
|
||||
testing.expect(is(builtin.TypeId.Int)(u8));
|
||||
testing.expect(!is(builtin.TypeId.Int)(f32));
|
||||
testing.expect(is(builtin.TypeId.Pointer)(*u8));
|
||||
testing.expect(is(builtin.TypeId.Void)(void));
|
||||
testing.expect(!is(builtin.TypeId.Optional)(anyerror));
|
||||
testing.expect(is(.Int)(u8));
|
||||
testing.expect(!is(.Int)(f32));
|
||||
testing.expect(is(.Pointer)(*u8));
|
||||
testing.expect(is(.Void)(void));
|
||||
testing.expect(!is(.Optional)(anyerror));
|
||||
}
|
||||
|
||||
pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
|
||||
@@ -138,9 +130,9 @@ pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
|
||||
}
|
||||
|
||||
test "std.meta.trait.isPtrTo" {
|
||||
testing.expect(!isPtrTo(builtin.TypeId.Struct)(struct {}));
|
||||
testing.expect(isPtrTo(builtin.TypeId.Struct)(*struct {}));
|
||||
testing.expect(!isPtrTo(builtin.TypeId.Struct)(**struct {}));
|
||||
testing.expect(!isPtrTo(.Struct)(struct {}));
|
||||
testing.expect(isPtrTo(.Struct)(*struct {}));
|
||||
testing.expect(!isPtrTo(.Struct)(**struct {}));
|
||||
}
|
||||
|
||||
///////////Strait trait Fns
|
||||
@@ -149,12 +141,10 @@ test "std.meta.trait.isPtrTo" {
|
||||
// Somewhat limited since we can't apply this logic to normal variables, fields, or
|
||||
// Fns yet. Should be isExternType?
|
||||
pub fn isExtern(comptime T: type) bool {
|
||||
const Extern = builtin.TypeInfo.ContainerLayout.Extern;
|
||||
const info = @typeInfo(T);
|
||||
return switch (info) {
|
||||
builtin.TypeId.Struct => |s| s.layout == Extern,
|
||||
builtin.TypeId.Union => |u| u.layout == Extern,
|
||||
builtin.TypeId.Enum => |e| e.layout == Extern,
|
||||
return switch (@typeInfo(T)) {
|
||||
.Struct => |s| s.layout == .Extern,
|
||||
.Union => |u| u.layout == .Extern,
|
||||
.Enum => |e| e.layout == .Extern,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@@ -169,12 +159,10 @@ test "std.meta.trait.isExtern" {
|
||||
}
|
||||
|
||||
pub fn isPacked(comptime T: type) bool {
|
||||
const Packed = builtin.TypeInfo.ContainerLayout.Packed;
|
||||
const info = @typeInfo(T);
|
||||
return switch (info) {
|
||||
builtin.TypeId.Struct => |s| s.layout == Packed,
|
||||
builtin.TypeId.Union => |u| u.layout == Packed,
|
||||
builtin.TypeId.Enum => |e| e.layout == Packed,
|
||||
return switch (@typeInfo(T)) {
|
||||
.Struct => |s| s.layout == .Packed,
|
||||
.Union => |u| u.layout == .Packed,
|
||||
.Enum => |e| e.layout == .Packed,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@@ -189,8 +177,8 @@ test "std.meta.trait.isPacked" {
|
||||
}
|
||||
|
||||
pub fn isUnsignedInt(comptime T: type) bool {
|
||||
return switch (@typeId(T)) {
|
||||
builtin.TypeId.Int => !@typeInfo(T).Int.is_signed,
|
||||
return switch (@typeInfo(T)) {
|
||||
.Int => |i| !i.is_signed,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@@ -203,9 +191,9 @@ test "isUnsignedInt" {
|
||||
}
|
||||
|
||||
pub fn isSignedInt(comptime T: type) bool {
|
||||
return switch (@typeId(T)) {
|
||||
builtin.TypeId.ComptimeInt => true,
|
||||
builtin.TypeId.Int => @typeInfo(T).Int.is_signed,
|
||||
return switch (@typeInfo(T)) {
|
||||
.ComptimeInt => true,
|
||||
.Int => |i| i.is_signed,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@@ -218,9 +206,8 @@ test "isSignedInt" {
|
||||
}
|
||||
|
||||
pub fn isSingleItemPtr(comptime T: type) bool {
|
||||
if (comptime is(builtin.TypeId.Pointer)(T)) {
|
||||
const info = @typeInfo(T);
|
||||
return info.Pointer.size == builtin.TypeInfo.Pointer.Size.One;
|
||||
if (comptime is(.Pointer)(T)) {
|
||||
return @typeInfo(T).Pointer.size == .One;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -233,9 +220,8 @@ test "std.meta.trait.isSingleItemPtr" {
|
||||
}
|
||||
|
||||
pub fn isManyItemPtr(comptime T: type) bool {
|
||||
if (comptime is(builtin.TypeId.Pointer)(T)) {
|
||||
const info = @typeInfo(T);
|
||||
return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Many;
|
||||
if (comptime is(.Pointer)(T)) {
|
||||
return @typeInfo(T).Pointer.size == .Many;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -249,9 +235,8 @@ test "std.meta.trait.isManyItemPtr" {
|
||||
}
|
||||
|
||||
pub fn isSlice(comptime T: type) bool {
|
||||
if (comptime is(builtin.TypeId.Pointer)(T)) {
|
||||
const info = @typeInfo(T);
|
||||
return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Slice;
|
||||
if (comptime is(.Pointer)(T)) {
|
||||
return @typeInfo(T).Pointer.size == .Slice;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -264,15 +249,13 @@ test "std.meta.trait.isSlice" {
|
||||
}
|
||||
|
||||
pub fn isIndexable(comptime T: type) bool {
|
||||
if (comptime is(builtin.TypeId.Pointer)(T)) {
|
||||
const info = @typeInfo(T);
|
||||
if (info.Pointer.size == builtin.TypeInfo.Pointer.Size.One) {
|
||||
if (comptime is(builtin.TypeId.Array)(meta.Child(T))) return true;
|
||||
return false;
|
||||
if (comptime is(.Pointer)(T)) {
|
||||
if (@typeInfo(T).Pointer.size == .One) {
|
||||
return (comptime is(.Array)(meta.Child(T)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return comptime is(builtin.TypeId.Array)(T);
|
||||
return comptime is(.Array)(T);
|
||||
}
|
||||
|
||||
test "std.meta.trait.isIndexable" {
|
||||
@@ -287,7 +270,7 @@ test "std.meta.trait.isIndexable" {
|
||||
|
||||
pub fn isNumber(comptime T: type) bool {
|
||||
return switch (@typeId(T)) {
|
||||
builtin.TypeId.Int, builtin.TypeId.Float, builtin.TypeId.ComptimeInt, builtin.TypeId.ComptimeFloat => true,
|
||||
.Int, .Float, .ComptimeInt, .ComptimeFloat => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@@ -307,9 +290,8 @@ test "std.meta.trait.isNumber" {
|
||||
}
|
||||
|
||||
pub fn isConstPtr(comptime T: type) bool {
|
||||
if (!comptime is(builtin.TypeId.Pointer)(T)) return false;
|
||||
const info = @typeInfo(T);
|
||||
return info.Pointer.is_const;
|
||||
if (!comptime is(.Pointer)(T)) return false;
|
||||
return @typeInfo(T).Pointer.is_const;
|
||||
}
|
||||
|
||||
test "std.meta.trait.isConstPtr" {
|
||||
@@ -322,11 +304,8 @@ test "std.meta.trait.isConstPtr" {
|
||||
}
|
||||
|
||||
pub fn isContainer(comptime T: type) bool {
|
||||
const info = @typeInfo(T);
|
||||
return switch (info) {
|
||||
builtin.TypeId.Struct => true,
|
||||
builtin.TypeId.Union => true,
|
||||
builtin.TypeId.Enum => true,
|
||||
return switch (@typeId(T)) {
|
||||
.Struct, .Union, .Enum => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -67,10 +67,8 @@ test "resolve DNS" {
|
||||
// DNS resolution not implemented on Windows yet.
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
var buf: [1000 * 10]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
|
||||
const address_list = net.getAddressList(a, "example.com", 80) catch |err| switch (err) {
|
||||
const address_list = net.getAddressList(testing.allocator, "example.com", 80) catch |err| switch (err) {
|
||||
// The tests are required to work even when there is no Internet connection,
|
||||
// so some of these errors we must accept and skip the test.
|
||||
error.UnknownHostName => return error.SkipZigTest,
|
||||
|
||||
+10
-14
@@ -95,8 +95,6 @@ test "cpu count" {
|
||||
}
|
||||
|
||||
test "AtomicFile" {
|
||||
var buffer: [1024]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(buffer[0..]).allocator;
|
||||
const test_out_file = "tmp_atomic_file_test_dest.txt";
|
||||
const test_content =
|
||||
\\ hello!
|
||||
@@ -108,7 +106,8 @@ test "AtomicFile" {
|
||||
try af.file.write(test_content);
|
||||
try af.finish();
|
||||
}
|
||||
const content = try io.readFileAlloc(allocator, test_out_file);
|
||||
const content = try io.readFileAlloc(testing.allocator, test_out_file);
|
||||
defer testing.allocator.free(content);
|
||||
expect(mem.eql(u8, content, test_content));
|
||||
|
||||
try fs.cwd().deleteFile(test_out_file);
|
||||
@@ -276,8 +275,11 @@ test "mmap" {
|
||||
testing.expectEqual(@as(usize, 1234), data.len);
|
||||
|
||||
// By definition the data returned by mmap is zero-filled
|
||||
std.mem.set(u8, data[0 .. data.len - 1], 0x55);
|
||||
testing.expect(mem.indexOfScalar(u8, data, 0).? == 1234 - 1);
|
||||
testing.expect(mem.eql(u8, data, &[_]u8{0x00} ** 1234));
|
||||
|
||||
// Make sure the memory is writeable as requested
|
||||
std.mem.set(u8, data, 0x55);
|
||||
testing.expect(mem.eql(u8, data, &[_]u8{0x55} ** 1234));
|
||||
}
|
||||
|
||||
const test_out_file = "os_tmp_test";
|
||||
@@ -300,10 +302,7 @@ test "mmap" {
|
||||
|
||||
// Map the whole file
|
||||
{
|
||||
const file = try fs.cwd().createFile(test_out_file, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
});
|
||||
const file = try fs.cwd().openFile(test_out_file, .{});
|
||||
defer file.close();
|
||||
|
||||
const data = try os.mmap(
|
||||
@@ -327,15 +326,12 @@ test "mmap" {
|
||||
|
||||
// Map the upper half of the file
|
||||
{
|
||||
const file = try fs.cwd().createFile(test_out_file, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
});
|
||||
const file = try fs.cwd().openFile(test_out_file, .{});
|
||||
defer file.close();
|
||||
|
||||
const data = try os.mmap(
|
||||
null,
|
||||
alloc_size,
|
||||
alloc_size / 2,
|
||||
os.PROT_READ,
|
||||
os.MAP_PRIVATE,
|
||||
file.handle,
|
||||
|
||||
+2
-4
@@ -27,10 +27,8 @@ pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
|
||||
}
|
||||
|
||||
test "getCwdAlloc" {
|
||||
// at least call it so it gets compiled
|
||||
var buf: [1000]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
||||
_ = getCwdAlloc(allocator) catch undefined;
|
||||
const cwd = try getCwdAlloc(testing.allocator);
|
||||
testing.allocator.free(cwd);
|
||||
}
|
||||
|
||||
/// Caller must free result when done.
|
||||
|
||||
+4
-4
@@ -1220,16 +1220,16 @@ test "sort fuzz testing" {
|
||||
const test_case_count = 10;
|
||||
var i: usize = 0;
|
||||
while (i < test_case_count) : (i += 1) {
|
||||
fuzzTest(&prng.random);
|
||||
try fuzzTest(&prng.random);
|
||||
}
|
||||
}
|
||||
|
||||
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
|
||||
|
||||
fn fuzzTest(rng: *std.rand.Random) void {
|
||||
fn fuzzTest(rng: *std.rand.Random) !void {
|
||||
const array_size = rng.range(usize, 0, 1000);
|
||||
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
|
||||
var array = fixed_allocator.allocator.alloc(IdAndValue, array_size) catch unreachable;
|
||||
var array = try testing.allocator.alloc(IdAndValue, array_size);
|
||||
defer testing.allocator.free(array);
|
||||
// populate with random data
|
||||
for (array) |*item, index| {
|
||||
item.id = index;
|
||||
|
||||
@@ -149,7 +149,7 @@ comptime {
|
||||
|
||||
@export(@import("compiler_rt/clzsi2.zig").__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
|
||||
|
||||
if (builtin.arch.isARM() and !is_test) {
|
||||
if ((builtin.arch.isARM() or builtin.arch.isThumb()) and !is_test) {
|
||||
@export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage });
|
||||
@export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
|
||||
@export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
|
||||
|
||||
@@ -270,7 +270,6 @@ pub const cpu = struct {
|
||||
.d,
|
||||
.f,
|
||||
.m,
|
||||
.relax,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -284,7 +283,6 @@ pub const cpu = struct {
|
||||
.d,
|
||||
.f,
|
||||
.m,
|
||||
.relax,
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
+17
-2
@@ -12,7 +12,7 @@ pub var allocator_instance = LeakCountAllocator.init(&base_allocator_instance.al
|
||||
pub const failing_allocator = &FailingAllocator.init(&base_allocator_instance.allocator, 0).allocator;
|
||||
|
||||
pub var base_allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]);
|
||||
var allocator_mem: [512 * 1024]u8 = undefined;
|
||||
var allocator_mem: [1024 * 1024]u8 = undefined;
|
||||
|
||||
/// This function is intended to be used only in tests. It prints diagnostics to stderr
|
||||
/// and then aborts when actual_error_union is not expected_error.
|
||||
@@ -56,7 +56,6 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void {
|
||||
.EnumLiteral,
|
||||
.Enum,
|
||||
.Fn,
|
||||
.Vector,
|
||||
.ErrorSet,
|
||||
=> {
|
||||
if (actual != expected) {
|
||||
@@ -88,6 +87,15 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void {
|
||||
|
||||
.Array => |array| expectEqualSlices(array.child, &expected, &actual),
|
||||
|
||||
.Vector => |vectorType| {
|
||||
var i: usize = 0;
|
||||
while (i < vectorType.len) : (i += 1) {
|
||||
if (!std.meta.eql(expected[i], actual[i])) {
|
||||
std.debug.panic("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
.Struct => |structType| {
|
||||
inline for (structType.fields) |field| {
|
||||
expectEqual(@field(expected, field.name), @field(actual, field.name));
|
||||
@@ -202,3 +210,10 @@ test "expectEqual nested array" {
|
||||
|
||||
expectEqual(a, b);
|
||||
}
|
||||
|
||||
test "expectEqual vector" {
|
||||
var a = @splat(4, @as(u32, 4));
|
||||
var b = @splat(4, @as(u32, 4));
|
||||
|
||||
expectEqual(a, b);
|
||||
}
|
||||
|
||||
+4
-6
@@ -617,16 +617,14 @@ test "utf8ToUtf16Le" {
|
||||
|
||||
test "utf8ToUtf16LeWithNull" {
|
||||
{
|
||||
var bytes: [128]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
const utf16 = try utf8ToUtf16LeWithNull(allocator, "𐐷");
|
||||
const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");
|
||||
defer testing.allocator.free(utf16);
|
||||
testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..]));
|
||||
testing.expect(utf16[2] == 0);
|
||||
}
|
||||
{
|
||||
var bytes: [128]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
const utf16 = try utf8ToUtf16LeWithNull(allocator, "\u{10FFFF}");
|
||||
const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");
|
||||
defer testing.allocator.free(utf16);
|
||||
testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..]));
|
||||
testing.expect(utf16[2] == 0);
|
||||
}
|
||||
|
||||
@@ -2886,8 +2886,7 @@ fn testCanonical(source: []const u8) !void {
|
||||
}
|
||||
|
||||
fn testError(source: []const u8) !void {
|
||||
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
|
||||
const tree = try std.zig.parse(&fixed_allocator.allocator, source);
|
||||
const tree = try std.zig.parse(std.testing.allocator, source);
|
||||
defer tree.deinit();
|
||||
|
||||
std.testing.expect(tree.errors.len != 0);
|
||||
|
||||
@@ -5123,6 +5123,8 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
|
||||
cast_node.rparen_token = try appendToken(c, .RParen, ")");
|
||||
return &cast_node.base;
|
||||
} else if (tok.id == .FloatLiteral) {
|
||||
if (lit_bytes[0] == '.')
|
||||
lit_bytes = try std.fmt.allocPrint(c.a(), "0{}", .{lit_bytes});
|
||||
if (tok.id.FloatLiteral == .None) {
|
||||
return transCreateNodeFloat(c, lit_bytes);
|
||||
}
|
||||
@@ -5340,12 +5342,27 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
||||
.LParen => {
|
||||
const inner_node = try parseCExpr(c, it, source, source_loc, scope);
|
||||
|
||||
if (it.peek().?.id == .RParen) {
|
||||
_ = it.next();
|
||||
if (it.peek().?.id != .LParen) {
|
||||
return inner_node;
|
||||
}
|
||||
_ = it.next();
|
||||
if (it.next().?.id != .RParen) {
|
||||
const first_tok = it.list.at(0);
|
||||
try failDecl(
|
||||
c,
|
||||
source_loc,
|
||||
source[first_tok.start..first_tok.end],
|
||||
"unable to translate C expr: expected ')'' here",
|
||||
.{},
|
||||
);
|
||||
return error.ParseError;
|
||||
}
|
||||
var saw_l_paren = false;
|
||||
switch (it.peek().?.id) {
|
||||
// (type)(to_cast)
|
||||
.LParen => {
|
||||
saw_l_paren = true;
|
||||
_ = it.next();
|
||||
},
|
||||
// (type)identifier
|
||||
.Identifier => {},
|
||||
else => return inner_node,
|
||||
}
|
||||
|
||||
// hack to get zig fmt to render a comma in builtin calls
|
||||
@@ -5353,7 +5370,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
||||
|
||||
const node_to_cast = try parseCExpr(c, it, source, source_loc, scope);
|
||||
|
||||
if (it.next().?.id != .RParen) {
|
||||
if (saw_l_paren and it.next().?.id != .RParen) {
|
||||
const first_tok = it.list.at(0);
|
||||
try failDecl(
|
||||
c,
|
||||
@@ -5494,7 +5511,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
||||
// hack to get zig fmt to render a comma in builtin calls
|
||||
_ = try appendToken(c, .Comma, ",");
|
||||
|
||||
const ptr_kind = blk:{
|
||||
const ptr_kind = blk: {
|
||||
// * token
|
||||
_ = it.prev();
|
||||
// last token of `node`
|
||||
|
||||
+3
-1
@@ -1999,6 +1999,9 @@ struct CFile {
|
||||
|
||||
// When adding fields, check if they should be added to the hash computation in build_with_cache
|
||||
struct CodeGen {
|
||||
// arena allocator destroyed just prior to codegen emit
|
||||
heap::ArenaAllocator *pass1_arena;
|
||||
|
||||
//////////////////////////// Runtime State
|
||||
LLVMModuleRef module;
|
||||
ZigList<ErrorMsg*> errors;
|
||||
@@ -2279,7 +2282,6 @@ struct ZigVar {
|
||||
Scope *parent_scope;
|
||||
Scope *child_scope;
|
||||
LLVMValueRef param_value_ref;
|
||||
IrExecutableSrc *owner_exec;
|
||||
|
||||
Buf *section_name;
|
||||
|
||||
|
||||
+94
-99
@@ -80,7 +80,7 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node,
|
||||
}
|
||||
|
||||
ZigType *new_type_table_entry(ZigTypeId id) {
|
||||
ZigType *entry = allocate<ZigType>(1);
|
||||
ZigType *entry = heap::c_allocator.create<ZigType>();
|
||||
entry->id = id;
|
||||
return entry;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope
|
||||
static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
|
||||
ZigType *import, Buf *bare_name)
|
||||
{
|
||||
ScopeDecls *scope = allocate<ScopeDecls>(1);
|
||||
ScopeDecls *scope = heap::c_allocator.create<ScopeDecls>();
|
||||
init_scope(g, &scope->base, ScopeIdDecls, node, parent);
|
||||
scope->decl_table.init(4);
|
||||
scope->container_type = container_type;
|
||||
@@ -151,7 +151,7 @@ static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent,
|
||||
|
||||
ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeBlock);
|
||||
ScopeBlock *scope = allocate<ScopeBlock>(1);
|
||||
ScopeBlock *scope = heap::c_allocator.create<ScopeBlock>();
|
||||
init_scope(g, &scope->base, ScopeIdBlock, node, parent);
|
||||
scope->name = node->data.block.name;
|
||||
return scope;
|
||||
@@ -159,20 +159,20 @@ ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
|
||||
ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeDefer);
|
||||
ScopeDefer *scope = allocate<ScopeDefer>(1);
|
||||
ScopeDefer *scope = heap::c_allocator.create<ScopeDefer>();
|
||||
init_scope(g, &scope->base, ScopeIdDefer, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeDefer);
|
||||
ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
|
||||
ScopeDeferExpr *scope = heap::c_allocator.create<ScopeDeferExpr>();
|
||||
init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
|
||||
ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
|
||||
ScopeVarDecl *scope = heap::c_allocator.create<ScopeVarDecl>();
|
||||
init_scope(g, &scope->base, ScopeIdVarDecl, node, parent);
|
||||
scope->var = var;
|
||||
return &scope->base;
|
||||
@@ -180,14 +180,14 @@ Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
|
||||
|
||||
ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeFnCallExpr);
|
||||
ScopeCImport *scope = allocate<ScopeCImport>(1);
|
||||
ScopeCImport *scope = heap::c_allocator.create<ScopeCImport>();
|
||||
init_scope(g, &scope->base, ScopeIdCImport, node, parent);
|
||||
buf_resize(&scope->buf, 0);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeLoop *scope = allocate<ScopeLoop>(1);
|
||||
ScopeLoop *scope = heap::c_allocator.create<ScopeLoop>();
|
||||
init_scope(g, &scope->base, ScopeIdLoop, node, parent);
|
||||
if (node->type == NodeTypeWhileExpr) {
|
||||
scope->name = node->data.while_expr.name;
|
||||
@@ -200,7 +200,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
}
|
||||
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime) {
|
||||
ScopeRuntime *scope = allocate<ScopeRuntime>(1);
|
||||
ScopeRuntime *scope = heap::c_allocator.create<ScopeRuntime>();
|
||||
scope->is_comptime = is_comptime;
|
||||
init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
|
||||
return &scope->base;
|
||||
@@ -208,37 +208,37 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc
|
||||
|
||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeSuspend);
|
||||
ScopeSuspend *scope = allocate<ScopeSuspend>(1);
|
||||
ScopeSuspend *scope = heap::c_allocator.create<ScopeSuspend>();
|
||||
init_scope(g, &scope->base, ScopeIdSuspend, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) {
|
||||
ScopeFnDef *scope = allocate<ScopeFnDef>(1);
|
||||
ScopeFnDef *scope = heap::c_allocator.create<ScopeFnDef>();
|
||||
init_scope(g, &scope->base, ScopeIdFnDef, node, parent);
|
||||
scope->fn_entry = fn_entry;
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeCompTime *scope = allocate<ScopeCompTime>(1);
|
||||
ScopeCompTime *scope = heap::c_allocator.create<ScopeCompTime>();
|
||||
init_scope(g, &scope->base, ScopeIdCompTime, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeTypeOf *scope = allocate<ScopeTypeOf>(1);
|
||||
ScopeTypeOf *scope = heap::c_allocator.create<ScopeTypeOf>();
|
||||
init_scope(g, &scope->base, ScopeIdTypeOf, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeExpr *scope = allocate<ScopeExpr>(1);
|
||||
ScopeExpr *scope = heap::c_allocator.create<ScopeExpr>();
|
||||
init_scope(g, &scope->base, ScopeIdExpr, node, parent);
|
||||
ScopeExpr *parent_expr = find_expr_scope(parent);
|
||||
if (parent_expr != nullptr) {
|
||||
size_t new_len = parent_expr->children_len + 1;
|
||||
parent_expr->children_ptr = reallocate_nonzero<ScopeExpr *>(
|
||||
parent_expr->children_ptr = heap::c_allocator.reallocate_nonzero<ScopeExpr *>(
|
||||
parent_expr->children_ptr, parent_expr->children_len, new_len);
|
||||
parent_expr->children_ptr[parent_expr->children_len] = scope;
|
||||
parent_expr->children_len = new_len;
|
||||
@@ -1104,8 +1104,8 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
|
||||
{
|
||||
Error err;
|
||||
|
||||
ZigValue *result = create_const_vals(1);
|
||||
ZigValue *result_ptr = create_const_vals(1);
|
||||
ZigValue *result = g->pass1_arena->create<ZigValue>();
|
||||
ZigValue *result_ptr = g->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialUndef;
|
||||
result->type = (type_entry == nullptr) ? g->builtin_types.entry_var : type_entry;
|
||||
result_ptr->special = ConstValSpecialStatic;
|
||||
@@ -1122,7 +1122,6 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
|
||||
{
|
||||
return g->invalid_inst_gen->value;
|
||||
}
|
||||
destroy(result_ptr, "ZigValue");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1507,7 +1506,7 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConventio
|
||||
|
||||
fn_type_id->cc = cc;
|
||||
fn_type_id->param_count = fn_proto->params.length;
|
||||
fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc);
|
||||
fn_type_id->param_info = heap::c_allocator.allocate<FnTypeParamInfo>(param_count_alloc);
|
||||
fn_type_id->next_param_index = 0;
|
||||
fn_type_id->is_var_args = fn_proto->is_var_args;
|
||||
}
|
||||
@@ -2171,7 +2170,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
|
||||
bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
|
||||
struct_type->data.structure.resolve_loop_flag_other = true;
|
||||
|
||||
uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;
|
||||
uint32_t *host_int_bytes = packed ? heap::c_allocator.allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;
|
||||
|
||||
size_t packed_bits_offset = 0;
|
||||
size_t next_offset = 0;
|
||||
@@ -2657,7 +2656,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
|
||||
}
|
||||
|
||||
enum_type->data.enumeration.src_field_count = field_count;
|
||||
enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
|
||||
enum_type->data.enumeration.fields = heap::c_allocator.allocate<TypeEnumField>(field_count);
|
||||
enum_type->data.enumeration.fields_by_name.init(field_count);
|
||||
|
||||
HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
|
||||
@@ -3034,7 +3033,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
union_type->data.unionation.src_field_count = field_count;
|
||||
union_type->data.unionation.fields = allocate<TypeUnionField>(field_count);
|
||||
union_type->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(field_count);
|
||||
union_type->data.unionation.fields_by_name.init(field_count);
|
||||
|
||||
Scope *scope = &union_type->data.unionation.decls_scope->base;
|
||||
@@ -3053,7 +3052,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
if (create_enum_type) {
|
||||
occupied_tag_values.init(field_count);
|
||||
|
||||
di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
|
||||
di_enumerators = heap::c_allocator.allocate<ZigLLVMDIEnumerator*>(field_count);
|
||||
|
||||
ZigType *tag_int_type;
|
||||
if (enum_type_node != nullptr) {
|
||||
@@ -3086,7 +3085,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
tag_type->data.enumeration.decl_node = decl_node;
|
||||
tag_type->data.enumeration.layout = ContainerLayoutAuto;
|
||||
tag_type->data.enumeration.src_field_count = field_count;
|
||||
tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
|
||||
tag_type->data.enumeration.fields = heap::c_allocator.allocate<TypeEnumField>(field_count);
|
||||
tag_type->data.enumeration.fields_by_name.init(field_count);
|
||||
tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
|
||||
} else if (enum_type_node != nullptr) {
|
||||
@@ -3106,7 +3105,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
return err;
|
||||
}
|
||||
tag_type = enum_type;
|
||||
covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
|
||||
covered_enum_fields = heap::c_allocator.allocate<bool>(enum_type->data.enumeration.src_field_count);
|
||||
} else {
|
||||
tag_type = nullptr;
|
||||
}
|
||||
@@ -3244,7 +3243,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
}
|
||||
covered_enum_fields[union_field->enum_field->decl_index] = true;
|
||||
} else {
|
||||
union_field->enum_field = allocate<TypeEnumField>(1);
|
||||
union_field->enum_field = heap::c_allocator.create<TypeEnumField>();
|
||||
union_field->enum_field->name = field_name;
|
||||
union_field->enum_field->decl_index = i;
|
||||
bigint_init_unsigned(&union_field->enum_field->value, i);
|
||||
@@ -3366,8 +3365,8 @@ static void get_fully_qualified_decl_name(CodeGen *g, Buf *buf, Tld *tld, bool i
|
||||
}
|
||||
|
||||
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
|
||||
ZigFn *fn_entry = allocate<ZigFn>(1, "ZigFn");
|
||||
fn_entry->ir_executable = allocate<IrExecutableSrc>(1, "IrExecutableSrc");
|
||||
ZigFn *fn_entry = heap::c_allocator.create<ZigFn>();
|
||||
fn_entry->ir_executable = heap::c_allocator.create<IrExecutableSrc>();
|
||||
|
||||
fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
|
||||
|
||||
@@ -3642,7 +3641,7 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
|
||||
return;
|
||||
}
|
||||
|
||||
TldFn *tld_fn = allocate<TldFn>(1);
|
||||
TldFn *tld_fn = heap::c_allocator.create<TldFn>();
|
||||
init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base);
|
||||
g->resolve_queue.append(&tld_fn->base);
|
||||
}
|
||||
@@ -3650,7 +3649,7 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
|
||||
static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
|
||||
assert(node->type == NodeTypeCompTime);
|
||||
|
||||
TldCompTime *tld_comptime = allocate<TldCompTime>(1);
|
||||
TldCompTime *tld_comptime = heap::c_allocator.create<TldCompTime>();
|
||||
init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base);
|
||||
g->resolve_queue.append(&tld_comptime->base);
|
||||
}
|
||||
@@ -3673,7 +3672,7 @@ void update_compile_var(CodeGen *g, Buf *name, ZigValue *value) {
|
||||
resolve_top_level_decl(g, tld, tld->source_node, false);
|
||||
assert(tld->id == TldIdVar && tld->resolution == TldResolutionOk);
|
||||
TldVar *tld_var = (TldVar *)tld;
|
||||
copy_const_val(tld_var->var->const_value, value);
|
||||
copy_const_val(g, tld_var->var->const_value, value);
|
||||
tld_var->var->var_type = value->type;
|
||||
tld_var->var->align_bytes = get_abi_alignment(g, value->type);
|
||||
}
|
||||
@@ -3693,7 +3692,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
{
|
||||
Buf *name = node->data.variable_declaration.symbol;
|
||||
VisibMod visib_mod = node->data.variable_declaration.visib_mod;
|
||||
TldVar *tld_var = allocate<TldVar>(1);
|
||||
TldVar *tld_var = heap::c_allocator.create<TldVar>();
|
||||
init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base);
|
||||
tld_var->extern_lib_name = node->data.variable_declaration.lib_name;
|
||||
add_top_level_decl(g, decls_scope, &tld_var->base);
|
||||
@@ -3709,7 +3708,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
}
|
||||
|
||||
VisibMod visib_mod = node->data.fn_proto.visib_mod;
|
||||
TldFn *tld_fn = allocate<TldFn>(1);
|
||||
TldFn *tld_fn = heap::c_allocator.create<TldFn>();
|
||||
init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base);
|
||||
tld_fn->extern_lib_name = node->data.fn_proto.lib_name;
|
||||
add_top_level_decl(g, decls_scope, &tld_fn->base);
|
||||
@@ -3718,7 +3717,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
}
|
||||
case NodeTypeUsingNamespace: {
|
||||
VisibMod visib_mod = node->data.using_namespace.visib_mod;
|
||||
TldUsingNamespace *tld_using_namespace = allocate<TldUsingNamespace>(1);
|
||||
TldUsingNamespace *tld_using_namespace = heap::c_allocator.create<TldUsingNamespace>();
|
||||
init_tld(&tld_using_namespace->base, TldIdUsingNamespace, nullptr, visib_mod, node, &decls_scope->base);
|
||||
add_top_level_decl(g, decls_scope, &tld_using_namespace->base);
|
||||
decls_scope->use_decls.append(tld_using_namespace);
|
||||
@@ -3845,7 +3844,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
|
||||
assert(const_value != nullptr);
|
||||
assert(var_type != nullptr);
|
||||
|
||||
ZigVar *variable_entry = allocate<ZigVar>(1);
|
||||
ZigVar *variable_entry = heap::c_allocator.create<ZigVar>();
|
||||
variable_entry->const_value = const_value;
|
||||
variable_entry->var_type = var_type;
|
||||
variable_entry->parent_scope = parent_scope;
|
||||
@@ -3984,7 +3983,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
|
||||
ZigType *type = explicit_type ? explicit_type : implicit_type;
|
||||
assert(type != nullptr); // should have been caught by the parser
|
||||
|
||||
ZigValue *init_val = (init_value != nullptr) ? init_value : create_const_runtime(type);
|
||||
ZigValue *init_val = (init_value != nullptr) ? init_value : create_const_runtime(g, type);
|
||||
|
||||
tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,
|
||||
is_const, init_val, &tld_var->base, type);
|
||||
@@ -4491,7 +4490,7 @@ static Error define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
}
|
||||
|
||||
ZigVar *var = add_variable(g, param_decl_node, fn_table_entry->child_scope,
|
||||
param_name, true, create_const_runtime(param_type), nullptr, param_type);
|
||||
param_name, true, create_const_runtime(g, param_type), nullptr, param_type);
|
||||
var->src_arg_index = i;
|
||||
fn_table_entry->child_scope = var->child_scope;
|
||||
var->shadowable = var->shadowable || is_var_args;
|
||||
@@ -4786,7 +4785,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
|
||||
} else {
|
||||
return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count;
|
||||
if (inferred_err_set_type->data.error_set.err_count > 0) {
|
||||
return_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
|
||||
return_err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
|
||||
for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) {
|
||||
return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i];
|
||||
}
|
||||
@@ -4919,7 +4918,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
|
||||
Buf *bare_name = buf_alloc();
|
||||
os_path_extname(src_basename, bare_name, nullptr);
|
||||
|
||||
RootStruct *root_struct = allocate<RootStruct>(1);
|
||||
RootStruct *root_struct = heap::c_allocator.create<RootStruct>();
|
||||
root_struct->package = package;
|
||||
root_struct->source_code = source_code;
|
||||
root_struct->line_offsets = tokenization.line_offsets;
|
||||
@@ -4946,7 +4945,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
|
||||
scan_decls(g, import_entry->data.structure.decls_scope, top_level_decl);
|
||||
}
|
||||
|
||||
TldContainer *tld_container = allocate<TldContainer>(1);
|
||||
TldContainer *tld_container = heap::c_allocator.create<TldContainer>();
|
||||
init_tld(&tld_container->base, TldIdContainer, namespace_name, VisibModPub, root_node, nullptr);
|
||||
tld_container->type_entry = import_entry;
|
||||
tld_container->decls_scope = import_entry->data.structure.decls_scope;
|
||||
@@ -5694,14 +5693,14 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
if (entry != nullptr) {
|
||||
return entry->value;
|
||||
}
|
||||
ZigValue *result = create_const_vals(1);
|
||||
ZigValue *result = g->pass1_arena->create<ZigValue>();
|
||||
result->type = type_entry;
|
||||
result->special = ConstValSpecialStatic;
|
||||
if (result->type->id == ZigTypeIdStruct) {
|
||||
// The fields array cannot be left unpopulated
|
||||
const ZigType *struct_type = result->type;
|
||||
const size_t field_count = struct_type->data.structure.src_field_count;
|
||||
result->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
|
||||
result->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
|
||||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
ZigType *field_type = resolve_struct_field_type(g, field);
|
||||
@@ -5786,7 +5785,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
|
||||
}
|
||||
|
||||
// first we build the underlying array
|
||||
ZigValue *array_val = create_const_vals(1);
|
||||
ZigValue *array_val = g->pass1_arena->create<ZigValue>();
|
||||
array_val->special = ConstValSpecialStatic;
|
||||
array_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), g->intern.for_zero_byte());
|
||||
array_val->data.x_array.special = ConstArraySpecialBuf;
|
||||
@@ -5803,7 +5802,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
|
||||
}
|
||||
|
||||
ZigValue *create_const_str_lit(CodeGen *g, Buf *str) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_str_lit(g, const_val, str);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5814,8 +5813,8 @@ void init_const_bigint(ZigValue *const_val, ZigType *type, const BigInt *bigint)
|
||||
bigint_init_bigint(&const_val->data.x_bigint, bigint);
|
||||
}
|
||||
|
||||
ZigValue *create_const_bigint(ZigType *type, const BigInt *bigint) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_bigint(CodeGen *g, ZigType *type, const BigInt *bigint) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_bigint(const_val, type, bigint);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5828,8 +5827,8 @@ void init_const_unsigned_negative(ZigValue *const_val, ZigType *type, uint64_t x
|
||||
const_val->data.x_bigint.is_negative = negative;
|
||||
}
|
||||
|
||||
ZigValue *create_const_unsigned_negative(ZigType *type, uint64_t x, bool negative) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_unsigned_negative(CodeGen *g, ZigType *type, uint64_t x, bool negative) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_unsigned_negative(const_val, type, x, negative);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5839,7 +5838,7 @@ void init_const_usize(CodeGen *g, ZigValue *const_val, uint64_t x) {
|
||||
}
|
||||
|
||||
ZigValue *create_const_usize(CodeGen *g, uint64_t x) {
|
||||
return create_const_unsigned_negative(g->builtin_types.entry_usize, x, false);
|
||||
return create_const_unsigned_negative(g, g->builtin_types.entry_usize, x, false);
|
||||
}
|
||||
|
||||
void init_const_signed(ZigValue *const_val, ZigType *type, int64_t x) {
|
||||
@@ -5848,8 +5847,8 @@ void init_const_signed(ZigValue *const_val, ZigType *type, int64_t x) {
|
||||
bigint_init_signed(&const_val->data.x_bigint, x);
|
||||
}
|
||||
|
||||
ZigValue *create_const_signed(ZigType *type, int64_t x) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_signed(CodeGen *g, ZigType *type, int64_t x) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_signed(const_val, type, x);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5860,8 +5859,8 @@ void init_const_null(ZigValue *const_val, ZigType *type) {
|
||||
const_val->data.x_optional = nullptr;
|
||||
}
|
||||
|
||||
ZigValue *create_const_null(ZigType *type) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_null(CodeGen *g, ZigType *type) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_null(const_val, type);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5893,8 +5892,8 @@ void init_const_float(ZigValue *const_val, ZigType *type, double value) {
|
||||
}
|
||||
}
|
||||
|
||||
ZigValue *create_const_float(ZigType *type, double value) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_float(CodeGen *g, ZigType *type, double value) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_float(const_val, type, value);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5905,8 +5904,8 @@ void init_const_enum(ZigValue *const_val, ZigType *type, const BigInt *tag) {
|
||||
bigint_init_bigint(&const_val->data.x_enum_tag, tag);
|
||||
}
|
||||
|
||||
ZigValue *create_const_enum(ZigType *type, const BigInt *tag) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_enum(CodeGen *g, ZigType *type, const BigInt *tag) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_enum(const_val, type, tag);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5919,7 +5918,7 @@ void init_const_bool(CodeGen *g, ZigValue *const_val, bool value) {
|
||||
}
|
||||
|
||||
ZigValue *create_const_bool(CodeGen *g, bool value) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_bool(g, const_val, value);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5929,8 +5928,8 @@ void init_const_runtime(ZigValue *const_val, ZigType *type) {
|
||||
const_val->type = type;
|
||||
}
|
||||
|
||||
ZigValue *create_const_runtime(ZigType *type) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *create_const_runtime(CodeGen *g, ZigType *type) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_runtime(const_val, type);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5942,7 +5941,7 @@ void init_const_type(CodeGen *g, ZigValue *const_val, ZigType *type_value) {
|
||||
}
|
||||
|
||||
ZigValue *create_const_type(CodeGen *g, ZigType *type_value) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_type(g, const_val, type_value);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5957,7 +5956,7 @@ void init_const_slice(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
|
||||
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = get_slice_type(g, ptr_type);
|
||||
const_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
|
||||
const_val->data.x_struct.fields = alloc_const_vals_ptrs(g, 2);
|
||||
|
||||
init_const_ptr_array(g, const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
|
||||
PtrLenUnknown);
|
||||
@@ -5965,7 +5964,7 @@ void init_const_slice(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
|
||||
}
|
||||
|
||||
ZigValue *create_const_slice(CodeGen *g, ZigValue *array_val, size_t start, size_t len, bool is_const) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_slice(g, const_val, array_val, start, len, is_const);
|
||||
return const_val;
|
||||
}
|
||||
@@ -5987,7 +5986,7 @@ void init_const_ptr_array(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
|
||||
ZigValue *create_const_ptr_array(CodeGen *g, ZigValue *array_val, size_t elem_index, bool is_const,
|
||||
PtrLen ptr_len)
|
||||
{
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_ptr_array(g, const_val, array_val, elem_index, is_const, ptr_len);
|
||||
return const_val;
|
||||
}
|
||||
@@ -6000,7 +5999,7 @@ void init_const_ptr_ref(CodeGen *g, ZigValue *const_val, ZigValue *pointee_val,
|
||||
}
|
||||
|
||||
ZigValue *create_const_ptr_ref(CodeGen *g, ZigValue *pointee_val, bool is_const) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_ptr_ref(g, const_val, pointee_val, is_const);
|
||||
return const_val;
|
||||
}
|
||||
@@ -6017,25 +6016,21 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ZigValue *const_val, ZigType *po
|
||||
ZigValue *create_const_ptr_hard_coded_addr(CodeGen *g, ZigType *pointee_type,
|
||||
size_t addr, bool is_const)
|
||||
{
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
|
||||
return const_val;
|
||||
}
|
||||
|
||||
ZigValue *create_const_vals(size_t count) {
|
||||
return allocate<ZigValue>(count, "ZigValue");
|
||||
ZigValue **alloc_const_vals_ptrs(CodeGen *g, size_t count) {
|
||||
return realloc_const_vals_ptrs(g, nullptr, 0, count);
|
||||
}
|
||||
|
||||
ZigValue **alloc_const_vals_ptrs(size_t count) {
|
||||
return realloc_const_vals_ptrs(nullptr, 0, count);
|
||||
}
|
||||
|
||||
ZigValue **realloc_const_vals_ptrs(ZigValue **ptr, size_t old_count, size_t new_count) {
|
||||
ZigValue **realloc_const_vals_ptrs(CodeGen *g, ZigValue **ptr, size_t old_count, size_t new_count) {
|
||||
assert(new_count >= old_count);
|
||||
|
||||
size_t new_item_count = new_count - old_count;
|
||||
ZigValue **result = reallocate(ptr, old_count, new_count, "ZigValue*");
|
||||
ZigValue *vals = create_const_vals(new_item_count);
|
||||
ZigValue **result = heap::c_allocator.reallocate(ptr, old_count, new_count);
|
||||
ZigValue *vals = g->pass1_arena->allocate<ZigValue>(new_item_count);
|
||||
for (size_t i = old_count; i < new_count; i += 1) {
|
||||
result[i] = &vals[i - old_count];
|
||||
}
|
||||
@@ -6050,8 +6045,8 @@ TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_c
|
||||
assert(new_count >= old_count);
|
||||
|
||||
size_t new_item_count = new_count - old_count;
|
||||
TypeStructField **result = reallocate(ptr, old_count, new_count, "TypeStructField*");
|
||||
TypeStructField *vals = allocate<TypeStructField>(new_item_count, "TypeStructField");
|
||||
TypeStructField **result = heap::c_allocator.reallocate(ptr, old_count, new_count);
|
||||
TypeStructField *vals = heap::c_allocator.allocate<TypeStructField>(new_item_count);
|
||||
for (size_t i = old_count; i < new_count; i += 1) {
|
||||
result[i] = &vals[i - old_count];
|
||||
}
|
||||
@@ -6062,7 +6057,7 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
|
||||
if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
|
||||
return orig_fn_type;
|
||||
|
||||
ZigType *fn_type = allocate_nonzero<ZigType>(1);
|
||||
ZigType *fn_type = heap::c_allocator.allocate_nonzero<ZigType>(1);
|
||||
*fn_type = *orig_fn_type;
|
||||
fn_type->data.fn.fn_type_id.cc = CallingConventionAsync;
|
||||
fn_type->llvm_type = nullptr;
|
||||
@@ -6236,11 +6231,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
ZigType *fn_type = get_async_fn_type(g, fn->type_entry);
|
||||
|
||||
if (fn->analyzed_executable.need_err_code_spill) {
|
||||
IrInstGenAlloca *alloca_gen = allocate<IrInstGenAlloca>(1);
|
||||
IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();
|
||||
alloca_gen->base.id = IrInstGenIdAlloca;
|
||||
alloca_gen->base.base.source_node = fn->proto_node;
|
||||
alloca_gen->base.base.scope = fn->child_scope;
|
||||
alloca_gen->base.value = allocate<ZigValue>(1, "ZigValue");
|
||||
alloca_gen->base.value = g->pass1_arena->create<ZigValue>();
|
||||
alloca_gen->base.value->type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
|
||||
alloca_gen->base.base.ref_count = 1;
|
||||
alloca_gen->name_hint = "";
|
||||
@@ -6942,9 +6937,9 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu
|
||||
return;
|
||||
}
|
||||
case ConstArraySpecialNone: {
|
||||
ZigValue *base = &array->data.s_none.elements[start];
|
||||
assert(base != nullptr);
|
||||
assert(start + len <= const_val->type->data.array.len);
|
||||
ZigValue *base = &array->data.s_none.elements[start];
|
||||
assert(len == 0 || base != nullptr);
|
||||
|
||||
buf_appendf(buf, "%s{", buf_ptr(type_name));
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
@@ -7375,7 +7370,7 @@ static void init_const_undefined(CodeGen *g, ZigValue *const_val) {
|
||||
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
size_t field_count = wanted_type->data.structure.src_field_count;
|
||||
const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
|
||||
const_val->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
|
||||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
ZigValue *field_val = const_val->data.x_struct.fields[i];
|
||||
field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]);
|
||||
@@ -7418,7 +7413,7 @@ void expand_undef_array(CodeGen *g, ZigValue *const_val) {
|
||||
return;
|
||||
case ConstArraySpecialUndef: {
|
||||
const_val->data.x_array.special = ConstArraySpecialNone;
|
||||
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
|
||||
const_val->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(elem_count);
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ZigValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
|
||||
element_val->type = elem_type;
|
||||
@@ -7437,7 +7432,7 @@ void expand_undef_array(CodeGen *g, ZigValue *const_val) {
|
||||
|
||||
const_val->data.x_array.special = ConstArraySpecialNone;
|
||||
assert(elem_count == buf_len(buf));
|
||||
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
|
||||
const_val->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(elem_count);
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ZigValue *this_char = &const_val->data.x_array.data.s_none.elements[i];
|
||||
this_char->special = ConstValSpecialStatic;
|
||||
@@ -7609,7 +7604,7 @@ const char *type_id_name(ZigTypeId id) {
|
||||
}
|
||||
|
||||
LinkLib *create_link_lib(Buf *name) {
|
||||
LinkLib *link_lib = allocate<LinkLib>(1);
|
||||
LinkLib *link_lib = heap::c_allocator.create<LinkLib>();
|
||||
link_lib->name = name;
|
||||
return link_lib;
|
||||
}
|
||||
@@ -8137,7 +8132,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
||||
|
||||
size_t field_count = struct_type->data.structure.src_field_count;
|
||||
// Every field could potentially have a generated padding field after it.
|
||||
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count * 2);
|
||||
LLVMTypeRef *element_types = heap::c_allocator.allocate<LLVMTypeRef>(field_count * 2);
|
||||
|
||||
bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
|
||||
size_t packed_bits_offset = 0;
|
||||
@@ -8272,7 +8267,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
||||
(unsigned)struct_type->data.structure.gen_field_count, packed);
|
||||
}
|
||||
|
||||
ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
|
||||
ZigLLVMDIType **di_element_types = heap::c_allocator.allocate<ZigLLVMDIType*>(debug_field_count);
|
||||
size_t debug_field_index = 0;
|
||||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
@@ -8389,7 +8384,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
|
||||
uint32_t field_count = enum_type->data.enumeration.src_field_count;
|
||||
|
||||
assert(field_count == 0 || enum_type->data.enumeration.fields != nullptr);
|
||||
ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
|
||||
ZigLLVMDIEnumerator **di_enumerators = heap::c_allocator.allocate<ZigLLVMDIEnumerator*>(field_count);
|
||||
|
||||
for (uint32_t i = 0; i < field_count; i += 1) {
|
||||
TypeEnumField *enum_field = &enum_type->data.enumeration.fields[i];
|
||||
@@ -8456,7 +8451,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
|
||||
}
|
||||
|
||||
ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
|
||||
ZigLLVMDIType **union_inner_di_types = heap::c_allocator.allocate<ZigLLVMDIType*>(gen_field_count);
|
||||
uint32_t field_count = union_type->data.unionation.src_field_count;
|
||||
for (uint32_t i = 0; i < field_count; i += 1) {
|
||||
TypeUnionField *union_field = &union_type->data.unionation.fields[i];
|
||||
@@ -8895,7 +8890,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
|
||||
param_di_types.append(get_llvm_di_type(g, gen_type));
|
||||
}
|
||||
if (is_async) {
|
||||
fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(2);
|
||||
fn_type->data.fn.gen_param_info = heap::c_allocator.allocate<FnGenParamInfo>(2);
|
||||
|
||||
ZigType *frame_type = get_any_frame_type(g, fn_type_id->return_type);
|
||||
gen_param_types.append(get_llvm_type(g, frame_type));
|
||||
@@ -8912,7 +8907,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
|
||||
fn_type->data.fn.gen_param_info[1].gen_index = 1;
|
||||
fn_type->data.fn.gen_param_info[1].type = g->builtin_types.entry_usize;
|
||||
} else {
|
||||
fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
|
||||
fn_type->data.fn.gen_param_info = heap::c_allocator.allocate<FnGenParamInfo>(fn_type_id->param_count);
|
||||
for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
|
||||
FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
|
||||
ZigType *type_entry = src_param_info->type;
|
||||
@@ -9369,7 +9364,7 @@ bool type_has_optional_repr(ZigType *ty) {
|
||||
}
|
||||
}
|
||||
|
||||
void copy_const_val(ZigValue *dest, ZigValue *src) {
|
||||
void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {
|
||||
uint32_t prev_align = dest->llvm_align;
|
||||
ConstParent prev_parent = dest->parent;
|
||||
memcpy(dest, src, sizeof(ZigValue));
|
||||
@@ -9378,26 +9373,26 @@ void copy_const_val(ZigValue *dest, ZigValue *src) {
|
||||
return;
|
||||
dest->parent = prev_parent;
|
||||
if (dest->type->id == ZigTypeIdStruct) {
|
||||
dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
|
||||
dest->data.x_struct.fields = alloc_const_vals_ptrs(g, dest->type->data.structure.src_field_count);
|
||||
for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
|
||||
copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);
|
||||
copy_const_val(g, dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);
|
||||
dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct;
|
||||
dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;
|
||||
dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
|
||||
}
|
||||
} else if (dest->type->id == ZigTypeIdArray) {
|
||||
if (dest->data.x_array.special == ConstArraySpecialNone) {
|
||||
dest->data.x_array.data.s_none.elements = create_const_vals(dest->type->data.array.len);
|
||||
dest->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(dest->type->data.array.len);
|
||||
for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {
|
||||
copy_const_val(&dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
|
||||
copy_const_val(g, &dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
|
||||
dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;
|
||||
dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;
|
||||
dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;
|
||||
}
|
||||
}
|
||||
} else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
|
||||
dest->data.x_optional = create_const_vals(1);
|
||||
copy_const_val(dest->data.x_optional, src->data.x_optional);
|
||||
dest->data.x_optional = g->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(g, dest->data.x_optional, src->data.x_optional);
|
||||
dest->data.x_optional->parent.id = ConstParentIdOptionalPayload;
|
||||
dest->data.x_optional->parent.data.p_optional_payload.optional_val = dest;
|
||||
}
|
||||
|
||||
+10
-11
@@ -128,22 +128,22 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str);
|
||||
ZigValue *create_const_str_lit(CodeGen *g, Buf *str);
|
||||
|
||||
void init_const_bigint(ZigValue *const_val, ZigType *type, const BigInt *bigint);
|
||||
ZigValue *create_const_bigint(ZigType *type, const BigInt *bigint);
|
||||
ZigValue *create_const_bigint(CodeGen *g, ZigType *type, const BigInt *bigint);
|
||||
|
||||
void init_const_unsigned_negative(ZigValue *const_val, ZigType *type, uint64_t x, bool negative);
|
||||
ZigValue *create_const_unsigned_negative(ZigType *type, uint64_t x, bool negative);
|
||||
ZigValue *create_const_unsigned_negative(CodeGen *g, ZigType *type, uint64_t x, bool negative);
|
||||
|
||||
void init_const_signed(ZigValue *const_val, ZigType *type, int64_t x);
|
||||
ZigValue *create_const_signed(ZigType *type, int64_t x);
|
||||
ZigValue *create_const_signed(CodeGen *g, ZigType *type, int64_t x);
|
||||
|
||||
void init_const_usize(CodeGen *g, ZigValue *const_val, uint64_t x);
|
||||
ZigValue *create_const_usize(CodeGen *g, uint64_t x);
|
||||
|
||||
void init_const_float(ZigValue *const_val, ZigType *type, double value);
|
||||
ZigValue *create_const_float(ZigType *type, double value);
|
||||
ZigValue *create_const_float(CodeGen *g, ZigType *type, double value);
|
||||
|
||||
void init_const_enum(ZigValue *const_val, ZigType *type, const BigInt *tag);
|
||||
ZigValue *create_const_enum(ZigType *type, const BigInt *tag);
|
||||
ZigValue *create_const_enum(CodeGen *g, ZigType *type, const BigInt *tag);
|
||||
|
||||
void init_const_bool(CodeGen *g, ZigValue *const_val, bool value);
|
||||
ZigValue *create_const_bool(CodeGen *g, bool value);
|
||||
@@ -152,7 +152,7 @@ void init_const_type(CodeGen *g, ZigValue *const_val, ZigType *type_value);
|
||||
ZigValue *create_const_type(CodeGen *g, ZigType *type_value);
|
||||
|
||||
void init_const_runtime(ZigValue *const_val, ZigType *type);
|
||||
ZigValue *create_const_runtime(ZigType *type);
|
||||
ZigValue *create_const_runtime(CodeGen *g, ZigType *type);
|
||||
|
||||
void init_const_ptr_ref(CodeGen *g, ZigValue *const_val, ZigValue *pointee_val, bool is_const);
|
||||
ZigValue *create_const_ptr_ref(CodeGen *g, ZigValue *pointee_val, bool is_const);
|
||||
@@ -172,11 +172,10 @@ void init_const_slice(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
|
||||
ZigValue *create_const_slice(CodeGen *g, ZigValue *array_val, size_t start, size_t len, bool is_const);
|
||||
|
||||
void init_const_null(ZigValue *const_val, ZigType *type);
|
||||
ZigValue *create_const_null(ZigType *type);
|
||||
ZigValue *create_const_null(CodeGen *g, ZigType *type);
|
||||
|
||||
ZigValue *create_const_vals(size_t count);
|
||||
ZigValue **alloc_const_vals_ptrs(size_t count);
|
||||
ZigValue **realloc_const_vals_ptrs(ZigValue **ptr, size_t old_count, size_t new_count);
|
||||
ZigValue **alloc_const_vals_ptrs(CodeGen *g, size_t count);
|
||||
ZigValue **realloc_const_vals_ptrs(CodeGen *g, ZigValue **ptr, size_t old_count, size_t new_count);
|
||||
|
||||
TypeStructField **alloc_type_struct_fields(size_t count);
|
||||
TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count);
|
||||
@@ -275,7 +274,7 @@ Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_targe
|
||||
ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
|
||||
ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry);
|
||||
bool is_anon_container(ZigType *ty);
|
||||
void copy_const_val(ZigValue *dest, ZigValue *src);
|
||||
void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src);
|
||||
bool type_has_optional_repr(ZigType *ty);
|
||||
bool is_opt_err_set(ZigType *ty);
|
||||
bool type_is_numeric(ZigType *ty);
|
||||
|
||||
+16
-16
@@ -93,7 +93,7 @@ static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count)
|
||||
if (dest->data.digit == 0) dest->digit_count = 0;
|
||||
return;
|
||||
}
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
for (size_t i = 0; i < digits_to_copy; i += 1) {
|
||||
uint64_t digit = (i < op->digit_count) ? op_digits[i] : 0;
|
||||
dest->data.digits[i] = digit;
|
||||
@@ -174,7 +174,7 @@ void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count,
|
||||
|
||||
dest->digit_count = digit_count;
|
||||
dest->is_negative = is_negative;
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(digit_count);
|
||||
memcpy(dest->data.digits, digits, sizeof(uint64_t) * digit_count);
|
||||
|
||||
bigint_normalize(dest);
|
||||
@@ -191,13 +191,13 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {
|
||||
}
|
||||
dest->is_negative = src->is_negative;
|
||||
dest->digit_count = src->digit_count;
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
memcpy(dest->data.digits, src->data.digits, sizeof(uint64_t) * dest->digit_count);
|
||||
}
|
||||
|
||||
void bigint_deinit(BigInt *bi) {
|
||||
if (bi->digit_count > 1)
|
||||
deallocate<uint64_t>(bi->data.digits, bi->digit_count);
|
||||
heap::c_allocator.deallocate(bi->data.digits, bi->digit_count);
|
||||
}
|
||||
|
||||
void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
|
||||
@@ -227,7 +227,7 @@ void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
|
||||
f128M_rem(&abs_val, &max_u64, &remainder);
|
||||
|
||||
dest->digit_count = 2;
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits[0] = f128M_to_ui64(&remainder, softfloat_round_minMag, false);
|
||||
dest->data.digits[1] = f128M_to_ui64(&amt, softfloat_round_minMag, false);
|
||||
bigint_normalize(dest);
|
||||
@@ -345,7 +345,7 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co
|
||||
if (dest->digit_count == 1) {
|
||||
digits = &dest->data.digit;
|
||||
} else {
|
||||
digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = digits;
|
||||
}
|
||||
|
||||
@@ -464,7 +464,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
}
|
||||
size_t i = 1;
|
||||
uint64_t first_digit = dest->data.digit;
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(max(op1->digit_count, op2->digit_count) + 1);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(max(op1->digit_count, op2->digit_count) + 1);
|
||||
dest->data.digits[0] = first_digit;
|
||||
|
||||
for (;;) {
|
||||
@@ -532,7 +532,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
return;
|
||||
}
|
||||
uint64_t first_digit = dest->data.digit;
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(bigger_op->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(bigger_op->digit_count);
|
||||
dest->data.digits[0] = first_digit;
|
||||
size_t i = 1;
|
||||
|
||||
@@ -1032,7 +1032,7 @@ static void bigint_unsigned_division(const BigInt *op1, const BigInt *op2, BigIn
|
||||
if (lhsWords == 1) {
|
||||
Quotient->data.digit = Make_64(Q[1], Q[0]);
|
||||
} else {
|
||||
Quotient->data.digits = allocate<uint64_t>(lhsWords);
|
||||
Quotient->data.digits = heap::c_allocator.allocate<uint64_t>(lhsWords);
|
||||
for (size_t i = 0; i < lhsWords; i += 1) {
|
||||
Quotient->data.digits[i] = Make_64(Q[i*2+1], Q[i*2]);
|
||||
}
|
||||
@@ -1046,7 +1046,7 @@ static void bigint_unsigned_division(const BigInt *op1, const BigInt *op2, BigIn
|
||||
if (rhsWords == 1) {
|
||||
Remainder->data.digit = Make_64(R[1], R[0]);
|
||||
} else {
|
||||
Remainder->data.digits = allocate<uint64_t>(rhsWords);
|
||||
Remainder->data.digits = heap::c_allocator.allocate<uint64_t>(rhsWords);
|
||||
for (size_t i = 0; i < rhsWords; i += 1) {
|
||||
Remainder->data.digits[i] = Make_64(R[i*2+1], R[i*2]);
|
||||
}
|
||||
@@ -1218,7 +1218,7 @@ void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
return;
|
||||
}
|
||||
dest->digit_count = max(op1->digit_count, op2->digit_count);
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
for (size_t i = 0; i < dest->digit_count; i += 1) {
|
||||
uint64_t digit = 0;
|
||||
if (i < op1->digit_count) {
|
||||
@@ -1262,7 +1262,7 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
}
|
||||
|
||||
dest->digit_count = max(op1->digit_count, op2->digit_count);
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
|
||||
size_t i = 0;
|
||||
for (; i < op1->digit_count && i < op2->digit_count; i += 1) {
|
||||
@@ -1308,7 +1308,7 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
return;
|
||||
}
|
||||
dest->digit_count = max(op1->digit_count, op2->digit_count);
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
size_t i = 0;
|
||||
for (; i < op1->digit_count && i < op2->digit_count; i += 1) {
|
||||
dest->data.digits[i] = op1_digits[i] ^ op2_digits[i];
|
||||
@@ -1358,7 +1358,7 @@ void bigint_shl(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
uint64_t digit_shift_count = shift_amt / 64;
|
||||
uint64_t leftover_shift_count = shift_amt % 64;
|
||||
|
||||
dest->data.digits = allocate<uint64_t>(op1->digit_count + digit_shift_count + 1);
|
||||
dest->data.digits = heap::c_allocator.allocate<uint64_t>(op1->digit_count + digit_shift_count + 1);
|
||||
dest->digit_count = digit_shift_count;
|
||||
uint64_t carry = 0;
|
||||
for (size_t i = 0; i < op1->digit_count; i += 1) {
|
||||
@@ -1421,7 +1421,7 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
|
||||
if (dest->digit_count == 1) {
|
||||
digits = &dest->data.digit;
|
||||
} else {
|
||||
digits = allocate<uint64_t>(dest->digit_count);
|
||||
digits = heap::c_allocator.allocate<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = digits;
|
||||
}
|
||||
|
||||
@@ -1492,7 +1492,7 @@ void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed
|
||||
}
|
||||
dest->digit_count = (bit_count + 63) / 64;
|
||||
assert(dest->digit_count >= op->digit_count);
|
||||
dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
dest->data.digits = heap::c_allocator.allocate_nonzero<uint64_t>(dest->digit_count);
|
||||
size_t i = 0;
|
||||
for (; i < op->digit_count; i += 1) {
|
||||
dest->data.digits[i] = ~op_digits[i];
|
||||
|
||||
+4
-5
@@ -50,7 +50,7 @@ static inline void buf_resize(Buf *buf, size_t new_len) {
|
||||
}
|
||||
|
||||
static inline Buf *buf_alloc_fixed(size_t size) {
|
||||
Buf *buf = allocate<Buf>(1);
|
||||
Buf *buf = heap::c_allocator.create<Buf>();
|
||||
buf_resize(buf, size);
|
||||
return buf;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ static inline void buf_deinit(Buf *buf) {
|
||||
|
||||
static inline void buf_destroy(Buf *buf) {
|
||||
buf_deinit(buf);
|
||||
free(buf);
|
||||
heap::c_allocator.destroy(buf);
|
||||
}
|
||||
|
||||
static inline void buf_init_from_mem(Buf *buf, const char *ptr, size_t len) {
|
||||
@@ -85,7 +85,7 @@ static inline void buf_init_from_buf(Buf *buf, Buf *other) {
|
||||
|
||||
static inline Buf *buf_create_from_mem(const char *ptr, size_t len) {
|
||||
assert(len != SIZE_MAX);
|
||||
Buf *buf = allocate<Buf>(1);
|
||||
Buf *buf = heap::c_allocator.create<Buf>();
|
||||
buf_init_from_mem(buf, ptr, len);
|
||||
return buf;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ static inline Buf *buf_slice(Buf *in_buf, size_t start, size_t end) {
|
||||
assert(end != SIZE_MAX);
|
||||
assert(start < buf_len(in_buf));
|
||||
assert(end <= buf_len(in_buf));
|
||||
Buf *out_buf = allocate<Buf>(1);
|
||||
Buf *out_buf = heap::c_allocator.create<Buf>();
|
||||
out_buf->list.resize(end - start + 1);
|
||||
memcpy(buf_ptr(out_buf), buf_ptr(in_buf) + start, end - start);
|
||||
out_buf->list.at(buf_len(out_buf)) = 0;
|
||||
@@ -211,5 +211,4 @@ static inline void buf_replace(Buf* buf, char from, char to) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+40
-35
@@ -21,6 +21,7 @@
|
||||
#include "userland.h"
|
||||
#include "dump_analysis.hpp"
|
||||
#include "softfloat.hpp"
|
||||
#include "mem_profile.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
@@ -57,7 +58,7 @@ static void init_darwin_native(CodeGen *g) {
|
||||
}
|
||||
|
||||
static ZigPackage *new_package(const char *root_src_dir, const char *root_src_path, const char *pkg_path) {
|
||||
ZigPackage *entry = allocate<ZigPackage>(1);
|
||||
ZigPackage *entry = heap::c_allocator.create<ZigPackage>();
|
||||
entry->package_table.init(4);
|
||||
buf_init_from_str(&entry->root_src_dir, root_src_dir);
|
||||
buf_init_from_str(&entry->root_src_path, root_src_path);
|
||||
@@ -4323,7 +4324,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
|
||||
}
|
||||
size_t field_count = arg_calc.field_index;
|
||||
|
||||
LLVMTypeRef *field_types = allocate_nonzero<LLVMTypeRef>(field_count);
|
||||
LLVMTypeRef *field_types = heap::c_allocator.allocate_nonzero<LLVMTypeRef>(field_count);
|
||||
LLVMGetStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc)), field_types);
|
||||
assert(LLVMCountStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc))) == arg_calc_start.field_index);
|
||||
|
||||
@@ -4676,8 +4677,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutableGen *executable, I
|
||||
instruction->return_count;
|
||||
size_t total_index = 0;
|
||||
size_t param_index = 0;
|
||||
LLVMTypeRef *param_types = allocate<LLVMTypeRef>(input_and_output_count);
|
||||
LLVMValueRef *param_values = allocate<LLVMValueRef>(input_and_output_count);
|
||||
LLVMTypeRef *param_types = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count);
|
||||
LLVMValueRef *param_values = heap::c_allocator.allocate<LLVMValueRef>(input_and_output_count);
|
||||
for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) {
|
||||
AsmOutput *asm_output = asm_expr->output_list.at(i);
|
||||
bool is_return = (asm_output->return_type != nullptr);
|
||||
@@ -4919,7 +4920,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *execut
|
||||
// second vector. These start at -1 and go down, and are easiest to use
|
||||
// with the ~ operator. Here we convert between the two formats.
|
||||
IrInstGen *mask = instruction->mask;
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(len_mask);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(len_mask);
|
||||
for (uint64_t i = 0; i < len_mask; i++) {
|
||||
if (mask->value->data.x_array.data.s_none.elements[i].special == ConstValSpecialUndef) {
|
||||
values[i] = LLVMGetUndef(LLVMInt32Type());
|
||||
@@ -4931,7 +4932,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *execut
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_mask_value = LLVMConstVector(values, len_mask);
|
||||
free(values);
|
||||
heap::c_allocator.deallocate(values, len_mask);
|
||||
|
||||
return LLVMBuildShuffleVector(g->builder,
|
||||
ir_llvm_value(g, instruction->a),
|
||||
@@ -4999,8 +5000,8 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns
|
||||
}
|
||||
|
||||
LLVMValueRef phi = LLVMBuildPhi(g->builder, phi_type, "");
|
||||
LLVMValueRef *incoming_values = allocate<LLVMValueRef>(instruction->incoming_count);
|
||||
LLVMBasicBlockRef *incoming_blocks = allocate<LLVMBasicBlockRef>(instruction->incoming_count);
|
||||
LLVMValueRef *incoming_values = heap::c_allocator.allocate<LLVMValueRef>(instruction->incoming_count);
|
||||
LLVMBasicBlockRef *incoming_blocks = heap::c_allocator.allocate<LLVMBasicBlockRef>(instruction->incoming_count);
|
||||
for (size_t i = 0; i < instruction->incoming_count; i += 1) {
|
||||
incoming_values[i] = ir_llvm_value(g, instruction->incoming_values[i]);
|
||||
incoming_blocks[i] = instruction->incoming_blocks[i]->llvm_exit_block;
|
||||
@@ -5972,12 +5973,12 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrI
|
||||
LLVMValueRef shift_amt = LLVMConstInt(get_llvm_type(g, extended_type), 8, false);
|
||||
if (is_vector) {
|
||||
extended_type = get_vector_type(g, expr_type->data.vector.len, extended_type);
|
||||
LLVMValueRef *values = allocate_nonzero<LLVMValueRef>(expr_type->data.vector.len);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate_nonzero<LLVMValueRef>(expr_type->data.vector.len);
|
||||
for (uint32_t i = 0; i < expr_type->data.vector.len; i += 1) {
|
||||
values[i] = shift_amt;
|
||||
}
|
||||
shift_amt = LLVMConstVector(values, expr_type->data.vector.len);
|
||||
free(values);
|
||||
heap::c_allocator.deallocate(values, expr_type->data.vector.len);
|
||||
}
|
||||
// aabbcc
|
||||
LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), "");
|
||||
@@ -7010,7 +7011,7 @@ check: switch (const_val->special) {
|
||||
}
|
||||
case ZigTypeIdStruct:
|
||||
{
|
||||
LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
|
||||
LLVMValueRef *fields = heap::c_allocator.allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
|
||||
size_t src_field_count = type_entry->data.structure.src_field_count;
|
||||
bool make_unnamed_struct = false;
|
||||
assert(type_entry->data.structure.resolve_status == ResolveStatusLLVMFull);
|
||||
@@ -7069,7 +7070,7 @@ check: switch (const_val->special) {
|
||||
} else {
|
||||
const LLVMValueRef AMT = LLVMConstInt(LLVMTypeOf(val), 8, false);
|
||||
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(size_in_bytes);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(size_in_bytes);
|
||||
for (size_t i = 0; i < size_in_bytes; i++) {
|
||||
const size_t idx = is_big_endian ? size_in_bytes - 1 - i : i;
|
||||
values[idx] = LLVMConstTruncOrBitCast(val, LLVMInt8Type());
|
||||
@@ -7133,7 +7134,7 @@ check: switch (const_val->special) {
|
||||
case ConstArraySpecialNone: {
|
||||
uint64_t extra_len_from_sentinel = (type_entry->data.array.sentinel != nullptr) ? 1 : 0;
|
||||
uint64_t full_len = len + extra_len_from_sentinel;
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(full_len);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(full_len);
|
||||
LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type);
|
||||
bool make_unnamed_struct = false;
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
@@ -7165,7 +7166,7 @@ check: switch (const_val->special) {
|
||||
case ConstArraySpecialUndef:
|
||||
return LLVMGetUndef(get_llvm_type(g, type_entry));
|
||||
case ConstArraySpecialNone: {
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(len);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(len);
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
ZigValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
|
||||
values[i] = gen_const_val(g, elem_value, "");
|
||||
@@ -7175,7 +7176,7 @@ check: switch (const_val->special) {
|
||||
case ConstArraySpecialBuf: {
|
||||
Buf *buf = const_val->data.x_array.data.s_buf;
|
||||
assert(buf_len(buf) == len);
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(len);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(len);
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
values[i] = LLVMConstInt(g->builtin_types.entry_u8->llvm_type, buf_ptr(buf)[i], false);
|
||||
}
|
||||
@@ -7377,7 +7378,7 @@ static void generate_error_name_table(CodeGen *g) {
|
||||
PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
|
||||
ZigType *str_type = get_slice_type(g, u8_ptr_type);
|
||||
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length);
|
||||
LLVMValueRef *values = heap::c_allocator.allocate<LLVMValueRef>(g->errors_by_index.length);
|
||||
values[0] = LLVMGetUndef(get_llvm_type(g, str_type));
|
||||
for (size_t i = 1; i < g->errors_by_index.length; i += 1) {
|
||||
ErrorTableEntry *err_entry = g->errors_by_index.at(i);
|
||||
@@ -7906,6 +7907,9 @@ static void do_code_gen(CodeGen *g) {
|
||||
}
|
||||
|
||||
static void zig_llvm_emit_output(CodeGen *g) {
|
||||
g->pass1_arena->destruct(&heap::c_allocator);
|
||||
g->pass1_arena = nullptr;
|
||||
|
||||
bool is_small = g->build_mode == BuildModeSmallRelease;
|
||||
|
||||
Buf *output_path = &g->o_file_output_path;
|
||||
@@ -8202,7 +8206,7 @@ static void define_intern_values(CodeGen *g) {
|
||||
}
|
||||
|
||||
static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {
|
||||
BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1);
|
||||
BuiltinFnEntry *builtin_fn = heap::c_allocator.create<BuiltinFnEntry>();
|
||||
buf_init_from_str(&builtin_fn->name, name);
|
||||
builtin_fn->id = id;
|
||||
builtin_fn->param_count = count;
|
||||
@@ -8919,16 +8923,16 @@ static void init(CodeGen *g) {
|
||||
define_builtin_types(g);
|
||||
define_intern_values(g);
|
||||
|
||||
IrInstGen *sentinel_instructions = allocate<IrInstGen>(2);
|
||||
IrInstGen *sentinel_instructions = heap::c_allocator.allocate<IrInstGen>(2);
|
||||
g->invalid_inst_gen = &sentinel_instructions[0];
|
||||
g->invalid_inst_gen->value = allocate<ZigValue>(1, "ZigValue");
|
||||
g->invalid_inst_gen->value = g->pass1_arena->create<ZigValue>();
|
||||
g->invalid_inst_gen->value->type = g->builtin_types.entry_invalid;
|
||||
|
||||
g->unreach_instruction = &sentinel_instructions[1];
|
||||
g->unreach_instruction->value = allocate<ZigValue>(1, "ZigValue");
|
||||
g->unreach_instruction->value = g->pass1_arena->create<ZigValue>();
|
||||
g->unreach_instruction->value->type = g->builtin_types.entry_unreachable;
|
||||
|
||||
g->invalid_inst_src = allocate<IrInstSrc>(1);
|
||||
g->invalid_inst_src = heap::c_allocator.create<IrInstSrc>();
|
||||
|
||||
define_builtin_fns(g);
|
||||
Error err;
|
||||
@@ -9010,7 +9014,7 @@ static void detect_libc(CodeGen *g) {
|
||||
buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os));
|
||||
|
||||
g->libc_include_dir_len = 4;
|
||||
g->libc_include_dir_list = allocate<Buf*>(g->libc_include_dir_len);
|
||||
g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(g->libc_include_dir_len);
|
||||
g->libc_include_dir_list[0] = arch_include_dir;
|
||||
g->libc_include_dir_list[1] = generic_include_dir;
|
||||
g->libc_include_dir_list[2] = arch_os_include_dir;
|
||||
@@ -9019,7 +9023,7 @@ static void detect_libc(CodeGen *g) {
|
||||
}
|
||||
|
||||
if (g->zig_target->is_native) {
|
||||
g->libc = allocate<ZigLibCInstallation>(1);
|
||||
g->libc = heap::c_allocator.create<ZigLibCInstallation>();
|
||||
|
||||
// search for native_libc.txt in following dirs:
|
||||
// - LOCAL_CACHE_DIR
|
||||
@@ -9099,7 +9103,7 @@ static void detect_libc(CodeGen *g) {
|
||||
size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0;
|
||||
size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs;
|
||||
g->libc_include_dir_len = 0;
|
||||
g->libc_include_dir_list = allocate<Buf*>(dir_count);
|
||||
g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(dir_count);
|
||||
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir;
|
||||
g->libc_include_dir_len += 1;
|
||||
@@ -9466,10 +9470,10 @@ static void update_test_functions_builtin_decl(CodeGen *g) {
|
||||
if ((err = type_resolve(g, struct_type, ResolveStatusSizeKnown)))
|
||||
zig_unreachable();
|
||||
|
||||
ZigValue *test_fn_array = create_const_vals(1);
|
||||
ZigValue *test_fn_array = g->pass1_arena->create<ZigValue>();
|
||||
test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length, nullptr);
|
||||
test_fn_array->special = ConstValSpecialStatic;
|
||||
test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length);
|
||||
test_fn_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(g->test_fns.length);
|
||||
|
||||
for (size_t i = 0; i < g->test_fns.length; i += 1) {
|
||||
ZigFn *test_fn_entry = g->test_fns.at(i);
|
||||
@@ -9480,7 +9484,7 @@ static void update_test_functions_builtin_decl(CodeGen *g) {
|
||||
this_val->parent.id = ConstParentIdArray;
|
||||
this_val->parent.data.p_array.array_val = test_fn_array;
|
||||
this_val->parent.data.p_array.elem_index = i;
|
||||
this_val->data.x_struct.fields = alloc_const_vals_ptrs(3);
|
||||
this_val->data.x_struct.fields = alloc_const_vals_ptrs(g, 3);
|
||||
|
||||
ZigValue *name_field = this_val->data.x_struct.fields[0];
|
||||
ZigValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee;
|
||||
@@ -9499,7 +9503,7 @@ static void update_test_functions_builtin_decl(CodeGen *g) {
|
||||
frame_size_field->data.x_optional = nullptr;
|
||||
|
||||
if (fn_is_async(test_fn_entry)) {
|
||||
frame_size_field->data.x_optional = create_const_vals(1);
|
||||
frame_size_field->data.x_optional = g->pass1_arena->create<ZigValue>();
|
||||
frame_size_field->data.x_optional->special = ConstValSpecialStatic;
|
||||
frame_size_field->data.x_optional->type = g->builtin_types.entry_usize;
|
||||
bigint_init_unsigned(&frame_size_field->data.x_optional->data.x_bigint,
|
||||
@@ -9634,7 +9638,7 @@ static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) {
|
||||
|
||||
Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose) {
|
||||
Error err;
|
||||
CacheHash *cache_hash = allocate<CacheHash>(1);
|
||||
CacheHash *cache_hash = heap::c_allocator.create<CacheHash>();
|
||||
Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(g->cache_dir));
|
||||
cache_init(cache_hash, manifest_dir);
|
||||
|
||||
@@ -10788,7 +10792,8 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
|
||||
OutType out_type, BuildMode build_mode, Buf *override_lib_dir,
|
||||
ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
|
||||
{
|
||||
CodeGen *g = allocate<CodeGen>(1);
|
||||
CodeGen *g = heap::c_allocator.create<CodeGen>();
|
||||
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
|
||||
g->main_progress_node = progress_node;
|
||||
|
||||
codegen_add_time_event(g, "Initialize");
|
||||
@@ -10931,35 +10936,35 @@ void codegen_switch_sub_prog_node(CodeGen *g, Stage2ProgressNode *node) {
|
||||
|
||||
ZigValue *CodeGen::Intern::for_undefined() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_undefined += 1;
|
||||
mem::intern_counters.x_undefined += 1;
|
||||
#endif
|
||||
return &this->x_undefined;
|
||||
}
|
||||
|
||||
ZigValue *CodeGen::Intern::for_void() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_void += 1;
|
||||
mem::intern_counters.x_void += 1;
|
||||
#endif
|
||||
return &this->x_void;
|
||||
}
|
||||
|
||||
ZigValue *CodeGen::Intern::for_null() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_null += 1;
|
||||
mem::intern_counters.x_null += 1;
|
||||
#endif
|
||||
return &this->x_null;
|
||||
}
|
||||
|
||||
ZigValue *CodeGen::Intern::for_unreachable() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_unreachable += 1;
|
||||
mem::intern_counters.x_unreachable += 1;
|
||||
#endif
|
||||
return &this->x_unreachable;
|
||||
}
|
||||
|
||||
ZigValue *CodeGen::Intern::for_zero_byte() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.zero_byte += 1;
|
||||
mem::intern_counters.zero_byte += 1;
|
||||
#endif
|
||||
return &this->zero_byte;
|
||||
}
|
||||
|
||||
+2
-2
@@ -99,7 +99,7 @@ void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {
|
||||
ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
|
||||
const char *source, Buf *msg)
|
||||
{
|
||||
ErrorMsg *err_msg = allocate<ErrorMsg>(1);
|
||||
ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
|
||||
err_msg->path = path;
|
||||
err_msg->line_start = line;
|
||||
err_msg->column_start = column;
|
||||
@@ -138,7 +138,7 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size
|
||||
ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
|
||||
Buf *source, ZigList<size_t> *line_offsets, Buf *msg)
|
||||
{
|
||||
ErrorMsg *err_msg = allocate<ErrorMsg>(1);
|
||||
ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
|
||||
err_msg->path = path;
|
||||
err_msg->line_start = line;
|
||||
err_msg->column_start = column;
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@ static const ZigGLibCLib glibc_libs[] = {
|
||||
Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose) {
|
||||
Error err;
|
||||
|
||||
ZigGLibCAbi *glibc_abi = allocate<ZigGLibCAbi>(1);
|
||||
ZigGLibCAbi *glibc_abi = heap::c_allocator.create<ZigGLibCAbi>();
|
||||
glibc_abi->vers_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "vers.txt", buf_ptr(zig_lib_dir));
|
||||
glibc_abi->fns_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "fns.txt", buf_ptr(zig_lib_dir));
|
||||
glibc_abi->abi_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "abi.txt", buf_ptr(zig_lib_dir));
|
||||
@@ -100,10 +100,10 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
|
||||
Optional<Slice<uint8_t>> opt_line = SplitIterator_next_separate(&it);
|
||||
if (!opt_line.is_some) break;
|
||||
|
||||
ver_list_base = allocate<ZigGLibCVerList>(glibc_abi->all_functions.length);
|
||||
ver_list_base = heap::c_allocator.allocate<ZigGLibCVerList>(glibc_abi->all_functions.length);
|
||||
SplitIterator line_it = memSplit(opt_line.value, str(" "));
|
||||
for (;;) {
|
||||
ZigTarget *target = allocate<ZigTarget>(1);
|
||||
ZigTarget *target = heap::c_allocator.create<ZigTarget>();
|
||||
Optional<Slice<uint8_t>> opt_target = SplitIterator_next(&line_it);
|
||||
if (!opt_target.is_some) break;
|
||||
|
||||
@@ -174,7 +174,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
|
||||
Error err;
|
||||
|
||||
Buf *cache_dir = get_global_cache_dir();
|
||||
CacheHash *cache_hash = allocate<CacheHash>(1);
|
||||
CacheHash *cache_hash = heap::c_allocator.create<CacheHash>();
|
||||
Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir));
|
||||
cache_init(cache_hash, manifest_dir);
|
||||
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ public:
|
||||
init_capacity(capacity);
|
||||
}
|
||||
void deinit(void) {
|
||||
free(_entries);
|
||||
heap::c_allocator.deallocate(_entries, _capacity);
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
if (old_entry->used)
|
||||
internal_put(old_entry->key, old_entry->value);
|
||||
}
|
||||
free(old_entries);
|
||||
heap::c_allocator.deallocate(old_entries, old_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ private:
|
||||
|
||||
void init_capacity(int capacity) {
|
||||
_capacity = capacity;
|
||||
_entries = allocate<Entry>(_capacity);
|
||||
_entries = heap::c_allocator.allocate<Entry>(_capacity);
|
||||
_size = 0;
|
||||
_max_distance_from_start_index = 0;
|
||||
for (int i = 0; i < _capacity; i += 1) {
|
||||
|
||||
+377
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "heap.hpp"
|
||||
#include "mem_profile.hpp"
|
||||
|
||||
namespace heap {
|
||||
|
||||
extern mem::Allocator &bootstrap_allocator;
|
||||
|
||||
//
|
||||
// BootstrapAllocator implementation is identical to CAllocator minus
|
||||
// profile profile functionality. Splitting off to a base interface doesn't
|
||||
// seem worthwhile.
|
||||
//
|
||||
|
||||
void BootstrapAllocator::init(const char *name) {}
|
||||
void BootstrapAllocator::deinit() {}
|
||||
|
||||
void *BootstrapAllocator::internal_allocate(const mem::TypeInfo &info, size_t count) {
|
||||
return mem::os::calloc(count, info.size);
|
||||
}
|
||||
|
||||
void *BootstrapAllocator::internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) {
|
||||
return mem::os::malloc(count * info.size);
|
||||
}
|
||||
|
||||
void *BootstrapAllocator::internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
auto new_ptr = this->internal_reallocate_nonzero(info, old_ptr, old_count, new_count);
|
||||
if (new_count > old_count)
|
||||
memset(reinterpret_cast<uint8_t *>(new_ptr) + (old_count * info.size), 0, (new_count - old_count) * info.size);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void *BootstrapAllocator::internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
return mem::os::realloc(old_ptr, new_count * info.size);
|
||||
}
|
||||
|
||||
void BootstrapAllocator::internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) {
|
||||
mem::os::free(ptr);
|
||||
}
|
||||
|
||||
void CAllocator::init(const char *name) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile = bootstrap_allocator.create<mem::Profile>();
|
||||
this->profile->init(name, "CAllocator");
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAllocator::deinit() {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
assert(this->profile);
|
||||
this->profile->deinit();
|
||||
bootstrap_allocator.destroy(this->profile);
|
||||
this->profile = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
CAllocator *CAllocator::construct(mem::Allocator *allocator, const char *name) {
|
||||
auto p = new(allocator->create<CAllocator>()) CAllocator();
|
||||
p->init(name);
|
||||
return p;
|
||||
}
|
||||
|
||||
void CAllocator::destruct(mem::Allocator *allocator) {
|
||||
this->deinit();
|
||||
allocator->destroy(this);
|
||||
}
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void CAllocator::print_report(FILE *file) {
|
||||
this->profile->print_report(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *CAllocator::internal_allocate(const mem::TypeInfo &info, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_alloc(info, count);
|
||||
#endif
|
||||
return mem::os::calloc(count, info.size);
|
||||
}
|
||||
|
||||
void *CAllocator::internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_alloc(info, count);
|
||||
#endif
|
||||
return mem::os::malloc(count * info.size);
|
||||
}
|
||||
|
||||
void *CAllocator::internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
auto new_ptr = this->internal_reallocate_nonzero(info, old_ptr, old_count, new_count);
|
||||
if (new_count > old_count)
|
||||
memset(reinterpret_cast<uint8_t *>(new_ptr) + (old_count * info.size), 0, (new_count - old_count) * info.size);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void *CAllocator::internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_dealloc(info, old_count);
|
||||
this->profile->record_alloc(info, new_count);
|
||||
#endif
|
||||
return mem::os::realloc(old_ptr, new_count * info.size);
|
||||
}
|
||||
|
||||
void CAllocator::internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_dealloc(info, count);
|
||||
#endif
|
||||
mem::os::free(ptr);
|
||||
}
|
||||
|
||||
struct ArenaAllocator::Impl {
|
||||
Allocator *backing;
|
||||
|
||||
// regular allocations bump through a segment of static size
|
||||
struct Segment {
|
||||
static constexpr size_t size = 65536;
|
||||
static constexpr size_t object_threshold = 4096;
|
||||
|
||||
uint8_t data[size];
|
||||
};
|
||||
|
||||
// active segment
|
||||
Segment *segment;
|
||||
size_t segment_offset;
|
||||
|
||||
// keep track of segments
|
||||
struct SegmentTrack {
|
||||
static constexpr size_t size = (4096 - sizeof(SegmentTrack *)) / sizeof(Segment *);
|
||||
|
||||
// null if first
|
||||
SegmentTrack *prev;
|
||||
Segment *segments[size];
|
||||
};
|
||||
static_assert(sizeof(SegmentTrack) <= 4096, "unwanted struct padding");
|
||||
|
||||
// active segment track
|
||||
SegmentTrack *segment_track;
|
||||
size_t segment_track_remain;
|
||||
|
||||
// individual allocations punted to backing allocator
|
||||
struct Object {
|
||||
uint8_t *ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
// keep track of objects
|
||||
struct ObjectTrack {
|
||||
static constexpr size_t size = (4096 - sizeof(ObjectTrack *)) / sizeof(Object);
|
||||
|
||||
// null if first
|
||||
ObjectTrack *prev;
|
||||
Object objects[size];
|
||||
};
|
||||
static_assert(sizeof(ObjectTrack) <= 4096, "unwanted struct padding");
|
||||
|
||||
// active object track
|
||||
ObjectTrack *object_track;
|
||||
size_t object_track_remain;
|
||||
|
||||
ATTRIBUTE_RETURNS_NOALIAS inline void *allocate(const mem::TypeInfo& info, size_t count);
|
||||
inline void *reallocate(const mem::TypeInfo& info, void *old_ptr, size_t old_count, size_t new_count);
|
||||
|
||||
inline void new_segment();
|
||||
inline void track_segment();
|
||||
inline void track_object(Object object);
|
||||
};
|
||||
|
||||
void *ArenaAllocator::Impl::allocate(const mem::TypeInfo& info, size_t count) {
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (info.size == 0 || count == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
const size_t nbytes = info.size * count;
|
||||
this->segment_offset = (this->segment_offset + (info.alignment - 1)) & ~(info.alignment - 1);
|
||||
if (nbytes >= Segment::object_threshold) {
|
||||
auto ptr = this->backing->allocate<uint8_t>(nbytes);
|
||||
this->track_object({ptr, nbytes});
|
||||
return ptr;
|
||||
}
|
||||
if (this->segment_offset + nbytes > Segment::size)
|
||||
this->new_segment();
|
||||
auto ptr = &this->segment->data[this->segment_offset];
|
||||
this->segment_offset += nbytes;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *ArenaAllocator::Impl::reallocate(const mem::TypeInfo& info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (info.size == 0 && old_ptr == nullptr)
|
||||
return nullptr;
|
||||
#endif
|
||||
const size_t new_nbytes = info.size * new_count;
|
||||
if (new_nbytes <= info.size * old_count)
|
||||
return old_ptr;
|
||||
const size_t old_nbytes = info.size * old_count;
|
||||
this->segment_offset = (this->segment_offset + (info.alignment - 1)) & ~(info.alignment - 1);
|
||||
if (new_nbytes >= Segment::object_threshold) {
|
||||
auto new_ptr = this->backing->allocate<uint8_t>(new_nbytes);
|
||||
this->track_object({new_ptr, new_nbytes});
|
||||
memcpy(new_ptr, old_ptr, old_nbytes);
|
||||
return new_ptr;
|
||||
}
|
||||
if (this->segment_offset + new_nbytes > Segment::size)
|
||||
this->new_segment();
|
||||
auto new_ptr = &this->segment->data[this->segment_offset];
|
||||
this->segment_offset += new_nbytes;
|
||||
memcpy(new_ptr, old_ptr, old_nbytes);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void ArenaAllocator::Impl::new_segment() {
|
||||
this->segment = this->backing->create<Segment>();
|
||||
this->segment_offset = 0;
|
||||
this->track_segment();
|
||||
}
|
||||
|
||||
void ArenaAllocator::Impl::track_segment() {
|
||||
assert(this->segment != nullptr);
|
||||
if (this->segment_track_remain < 1) {
|
||||
auto prev = this->segment_track;
|
||||
this->segment_track = this->backing->create<SegmentTrack>();
|
||||
this->segment_track->prev = prev;
|
||||
this->segment_track_remain = SegmentTrack::size;
|
||||
}
|
||||
this->segment_track_remain -= 1;
|
||||
this->segment_track->segments[this->segment_track_remain] = this->segment;
|
||||
}
|
||||
|
||||
void ArenaAllocator::Impl::track_object(Object object) {
|
||||
if (this->object_track_remain < 1) {
|
||||
auto prev = this->object_track;
|
||||
this->object_track = this->backing->create<ObjectTrack>();
|
||||
this->object_track->prev = prev;
|
||||
this->object_track_remain = ObjectTrack::size;
|
||||
}
|
||||
this->object_track_remain -= 1;
|
||||
this->object_track->objects[this->object_track_remain] = object;
|
||||
}
|
||||
|
||||
void ArenaAllocator::init(Allocator *backing, const char *name) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile = bootstrap_allocator.create<mem::Profile>();
|
||||
this->profile->init(name, "ArenaAllocator");
|
||||
#endif
|
||||
this->impl = bootstrap_allocator.create<Impl>();
|
||||
{
|
||||
auto &r = *this->impl;
|
||||
r.backing = backing;
|
||||
r.segment_offset = Impl::Segment::size;
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaAllocator::deinit() {
|
||||
auto &backing = *this->impl->backing;
|
||||
|
||||
// segments
|
||||
if (this->impl->segment_track) {
|
||||
// active track is not full and bounded by track_remain
|
||||
auto prev = this->impl->segment_track->prev;
|
||||
{
|
||||
auto t = this->impl->segment_track;
|
||||
for (size_t i = this->impl->segment_track_remain; i < Impl::SegmentTrack::size; ++i)
|
||||
backing.destroy(t->segments[i]);
|
||||
backing.destroy(t);
|
||||
}
|
||||
|
||||
// previous tracks are full
|
||||
for (auto t = prev; t != nullptr;) {
|
||||
for (size_t i = 0; i < Impl::SegmentTrack::size; ++i)
|
||||
backing.destroy(t->segments[i]);
|
||||
prev = t->prev;
|
||||
backing.destroy(t);
|
||||
t = prev;
|
||||
}
|
||||
}
|
||||
|
||||
// objects
|
||||
if (this->impl->object_track) {
|
||||
// active track is not full and bounded by track_remain
|
||||
auto prev = this->impl->object_track->prev;
|
||||
{
|
||||
auto t = this->impl->object_track;
|
||||
for (size_t i = this->impl->object_track_remain; i < Impl::ObjectTrack::size; ++i) {
|
||||
auto &obj = t->objects[i];
|
||||
backing.deallocate(obj.ptr, obj.len);
|
||||
}
|
||||
backing.destroy(t);
|
||||
}
|
||||
|
||||
// previous tracks are full
|
||||
for (auto t = prev; t != nullptr;) {
|
||||
for (size_t i = 0; i < Impl::ObjectTrack::size; ++i) {
|
||||
auto &obj = t->objects[i];
|
||||
backing.deallocate(obj.ptr, obj.len);
|
||||
}
|
||||
prev = t->prev;
|
||||
backing.destroy(t);
|
||||
t = prev;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
assert(this->profile);
|
||||
this->profile->deinit();
|
||||
bootstrap_allocator.destroy(this->profile);
|
||||
this->profile = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ArenaAllocator *ArenaAllocator::construct(mem::Allocator *allocator, mem::Allocator *backing, const char *name) {
|
||||
auto p = new(allocator->create<ArenaAllocator>()) ArenaAllocator;
|
||||
p->init(backing, name);
|
||||
return p;
|
||||
}
|
||||
|
||||
void ArenaAllocator::destruct(mem::Allocator *allocator) {
|
||||
this->deinit();
|
||||
allocator->destroy(this);
|
||||
}
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void ArenaAllocator::print_report(FILE *file) {
|
||||
this->profile->print_report(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *ArenaAllocator::internal_allocate(const mem::TypeInfo &info, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_alloc(info, count);
|
||||
#endif
|
||||
return this->impl->allocate(info, count);
|
||||
}
|
||||
|
||||
void *ArenaAllocator::internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_alloc(info, count);
|
||||
#endif
|
||||
return this->impl->allocate(info, count);
|
||||
}
|
||||
|
||||
void *ArenaAllocator::internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
return this->internal_reallocate_nonzero(info, old_ptr, old_count, new_count);
|
||||
}
|
||||
|
||||
void *ArenaAllocator::internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_dealloc(info, old_count);
|
||||
this->profile->record_alloc(info, new_count);
|
||||
#endif
|
||||
return this->impl->reallocate(info, old_ptr, old_count, new_count);
|
||||
}
|
||||
|
||||
void ArenaAllocator::internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
this->profile->record_dealloc(info, count);
|
||||
#endif
|
||||
// noop
|
||||
}
|
||||
|
||||
BootstrapAllocator bootstrap_allocator_state;
|
||||
mem::Allocator &bootstrap_allocator = bootstrap_allocator_state;
|
||||
|
||||
CAllocator c_allocator_state;
|
||||
mem::Allocator &c_allocator = c_allocator_state;
|
||||
|
||||
} // namespace heap
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_HEAP_HPP
|
||||
#define ZIG_HEAP_HPP
|
||||
|
||||
#include "config.h"
|
||||
#include "util_base.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
namespace mem {
|
||||
struct Profile;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace heap {
|
||||
|
||||
struct BootstrapAllocator final : mem::Allocator {
|
||||
void init(const char *name);
|
||||
void deinit();
|
||||
void destruct(Allocator *allocator) {}
|
||||
|
||||
private:
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate(const mem::TypeInfo &info, size_t count) final;
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) final;
|
||||
void *internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void *internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) final;
|
||||
};
|
||||
|
||||
struct CAllocator final : mem::Allocator {
|
||||
void init(const char *name);
|
||||
void deinit();
|
||||
|
||||
static CAllocator *construct(mem::Allocator *allocator, const char *name);
|
||||
void destruct(mem::Allocator *allocator) final;
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void print_report(FILE *file = nullptr);
|
||||
#endif
|
||||
|
||||
private:
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate(const mem::TypeInfo &info, size_t count) final;
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) final;
|
||||
void *internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void *internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) final;
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
mem::Profile *profile;
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// arena allocator
|
||||
//
|
||||
// - allocations are backed by the underlying allocator's memory
|
||||
// - allocations are N:1 relationship to underlying allocations
|
||||
// - dellocations are noops
|
||||
// - deinit() releases all underlying memory
|
||||
//
|
||||
struct ArenaAllocator final : mem::Allocator {
|
||||
void init(Allocator *backing, const char *name);
|
||||
void deinit();
|
||||
|
||||
static ArenaAllocator *construct(mem::Allocator *allocator, mem::Allocator *backing, const char *name);
|
||||
void destruct(mem::Allocator *allocator) final;
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void print_report(FILE *file = nullptr);
|
||||
#endif
|
||||
|
||||
private:
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate(const mem::TypeInfo &info, size_t count) final;
|
||||
ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) final;
|
||||
void *internal_reallocate(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void *internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final;
|
||||
void internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) final;
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
mem::Profile *profile;
|
||||
#endif
|
||||
|
||||
struct Impl;
|
||||
Impl *impl;
|
||||
};
|
||||
|
||||
extern BootstrapAllocator bootstrap_allocator_state;
|
||||
extern mem::Allocator &bootstrap_allocator;
|
||||
|
||||
extern CAllocator c_allocator_state;
|
||||
extern mem::Allocator &c_allocator;
|
||||
|
||||
} // namespace heap
|
||||
|
||||
#endif
|
||||
+557
-560
@@ -267,479 +267,470 @@ static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
|
||||
static ResultLoc *no_result_loc(void);
|
||||
static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value);
|
||||
static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr);
|
||||
static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty);
|
||||
|
||||
static void destroy_instruction_src(IrInstSrc *inst) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
const char *name = ir_inst_src_type_str(inst->id);
|
||||
#else
|
||||
const char *name = nullptr;
|
||||
#endif
|
||||
switch (inst->id) {
|
||||
case IrInstSrcIdInvalid:
|
||||
zig_unreachable();
|
||||
case IrInstSrcIdReturn:
|
||||
return destroy(reinterpret_cast<IrInstSrcReturn *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturn *>(inst));
|
||||
case IrInstSrcIdConst:
|
||||
return destroy(reinterpret_cast<IrInstSrcConst *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcConst *>(inst));
|
||||
case IrInstSrcIdBinOp:
|
||||
return destroy(reinterpret_cast<IrInstSrcBinOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBinOp *>(inst));
|
||||
case IrInstSrcIdMergeErrSets:
|
||||
return destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst));
|
||||
case IrInstSrcIdDeclVar:
|
||||
return destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst));
|
||||
case IrInstSrcIdCall:
|
||||
return destroy(reinterpret_cast<IrInstSrcCall *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst));
|
||||
case IrInstSrcIdCallExtra:
|
||||
return destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst));
|
||||
case IrInstSrcIdUnOp:
|
||||
return destroy(reinterpret_cast<IrInstSrcUnOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst));
|
||||
case IrInstSrcIdCondBr:
|
||||
return destroy(reinterpret_cast<IrInstSrcCondBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst));
|
||||
case IrInstSrcIdBr:
|
||||
return destroy(reinterpret_cast<IrInstSrcBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst));
|
||||
case IrInstSrcIdPhi:
|
||||
return destroy(reinterpret_cast<IrInstSrcPhi *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst));
|
||||
case IrInstSrcIdContainerInitList:
|
||||
return destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst));
|
||||
case IrInstSrcIdContainerInitFields:
|
||||
return destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst));
|
||||
case IrInstSrcIdUnreachable:
|
||||
return destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst));
|
||||
case IrInstSrcIdElemPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst));
|
||||
case IrInstSrcIdVarPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst));
|
||||
case IrInstSrcIdLoadPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst));
|
||||
case IrInstSrcIdStorePtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst));
|
||||
case IrInstSrcIdTypeOf:
|
||||
return destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst));
|
||||
case IrInstSrcIdFieldPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst));
|
||||
case IrInstSrcIdSetCold:
|
||||
return destroy(reinterpret_cast<IrInstSrcSetCold *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst));
|
||||
case IrInstSrcIdSetRuntimeSafety:
|
||||
return destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst));
|
||||
case IrInstSrcIdSetFloatMode:
|
||||
return destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst));
|
||||
case IrInstSrcIdArrayType:
|
||||
return destroy(reinterpret_cast<IrInstSrcArrayType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst));
|
||||
case IrInstSrcIdSliceType:
|
||||
return destroy(reinterpret_cast<IrInstSrcSliceType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst));
|
||||
case IrInstSrcIdAnyFrameType:
|
||||
return destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst));
|
||||
case IrInstSrcIdAsm:
|
||||
return destroy(reinterpret_cast<IrInstSrcAsm *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst));
|
||||
case IrInstSrcIdSizeOf:
|
||||
return destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst));
|
||||
case IrInstSrcIdTestNonNull:
|
||||
return destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst));
|
||||
case IrInstSrcIdOptionalUnwrapPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst));
|
||||
case IrInstSrcIdPopCount:
|
||||
return destroy(reinterpret_cast<IrInstSrcPopCount *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst));
|
||||
case IrInstSrcIdClz:
|
||||
return destroy(reinterpret_cast<IrInstSrcClz *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst));
|
||||
case IrInstSrcIdCtz:
|
||||
return destroy(reinterpret_cast<IrInstSrcCtz *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst));
|
||||
case IrInstSrcIdBswap:
|
||||
return destroy(reinterpret_cast<IrInstSrcBswap *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst));
|
||||
case IrInstSrcIdBitReverse:
|
||||
return destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst));
|
||||
case IrInstSrcIdSwitchBr:
|
||||
return destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst));
|
||||
case IrInstSrcIdSwitchVar:
|
||||
return destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst));
|
||||
case IrInstSrcIdSwitchElseVar:
|
||||
return destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst));
|
||||
case IrInstSrcIdSwitchTarget:
|
||||
return destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst));
|
||||
case IrInstSrcIdImport:
|
||||
return destroy(reinterpret_cast<IrInstSrcImport *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst));
|
||||
case IrInstSrcIdRef:
|
||||
return destroy(reinterpret_cast<IrInstSrcRef *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst));
|
||||
case IrInstSrcIdCompileErr:
|
||||
return destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst));
|
||||
case IrInstSrcIdCompileLog:
|
||||
return destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst));
|
||||
case IrInstSrcIdErrName:
|
||||
return destroy(reinterpret_cast<IrInstSrcErrName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst));
|
||||
case IrInstSrcIdCImport:
|
||||
return destroy(reinterpret_cast<IrInstSrcCImport *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst));
|
||||
case IrInstSrcIdCInclude:
|
||||
return destroy(reinterpret_cast<IrInstSrcCInclude *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst));
|
||||
case IrInstSrcIdCDefine:
|
||||
return destroy(reinterpret_cast<IrInstSrcCDefine *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst));
|
||||
case IrInstSrcIdCUndef:
|
||||
return destroy(reinterpret_cast<IrInstSrcCUndef *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst));
|
||||
case IrInstSrcIdEmbedFile:
|
||||
return destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst));
|
||||
case IrInstSrcIdCmpxchg:
|
||||
return destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst));
|
||||
case IrInstSrcIdFence:
|
||||
return destroy(reinterpret_cast<IrInstSrcFence *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst));
|
||||
case IrInstSrcIdTruncate:
|
||||
return destroy(reinterpret_cast<IrInstSrcTruncate *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst));
|
||||
case IrInstSrcIdIntCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst));
|
||||
case IrInstSrcIdFloatCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
|
||||
case IrInstSrcIdErrSetCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
|
||||
case IrInstSrcIdFromBytes:
|
||||
return destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst));
|
||||
case IrInstSrcIdToBytes:
|
||||
return destroy(reinterpret_cast<IrInstSrcToBytes *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcToBytes *>(inst));
|
||||
case IrInstSrcIdIntToFloat:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
|
||||
case IrInstSrcIdFloatToInt:
|
||||
return destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));
|
||||
case IrInstSrcIdBoolToInt:
|
||||
return destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));
|
||||
case IrInstSrcIdIntType:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntType *>(inst));
|
||||
case IrInstSrcIdVectorType:
|
||||
return destroy(reinterpret_cast<IrInstSrcVectorType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));
|
||||
case IrInstSrcIdShuffleVector:
|
||||
return destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst));
|
||||
case IrInstSrcIdSplat:
|
||||
return destroy(reinterpret_cast<IrInstSrcSplat *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst));
|
||||
case IrInstSrcIdBoolNot:
|
||||
return destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst));
|
||||
case IrInstSrcIdMemset:
|
||||
return destroy(reinterpret_cast<IrInstSrcMemset *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst));
|
||||
case IrInstSrcIdMemcpy:
|
||||
return destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));
|
||||
case IrInstSrcIdSlice:
|
||||
return destroy(reinterpret_cast<IrInstSrcSlice *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));
|
||||
case IrInstSrcIdMemberCount:
|
||||
return destroy(reinterpret_cast<IrInstSrcMemberCount *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberCount *>(inst));
|
||||
case IrInstSrcIdMemberType:
|
||||
return destroy(reinterpret_cast<IrInstSrcMemberType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberType *>(inst));
|
||||
case IrInstSrcIdMemberName:
|
||||
return destroy(reinterpret_cast<IrInstSrcMemberName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberName *>(inst));
|
||||
case IrInstSrcIdBreakpoint:
|
||||
return destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));
|
||||
case IrInstSrcIdReturnAddress:
|
||||
return destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst));
|
||||
case IrInstSrcIdFrameAddress:
|
||||
return destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst));
|
||||
case IrInstSrcIdFrameHandle:
|
||||
return destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst));
|
||||
case IrInstSrcIdFrameType:
|
||||
return destroy(reinterpret_cast<IrInstSrcFrameType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst));
|
||||
case IrInstSrcIdFrameSize:
|
||||
return destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst));
|
||||
case IrInstSrcIdAlignOf:
|
||||
return destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst));
|
||||
case IrInstSrcIdOverflowOp:
|
||||
return destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst));
|
||||
case IrInstSrcIdTestErr:
|
||||
return destroy(reinterpret_cast<IrInstSrcTestErr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst));
|
||||
case IrInstSrcIdUnwrapErrCode:
|
||||
return destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst));
|
||||
case IrInstSrcIdUnwrapErrPayload:
|
||||
return destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst));
|
||||
case IrInstSrcIdFnProto:
|
||||
return destroy(reinterpret_cast<IrInstSrcFnProto *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst));
|
||||
case IrInstSrcIdTestComptime:
|
||||
return destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst));
|
||||
case IrInstSrcIdPtrCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst));
|
||||
case IrInstSrcIdBitCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcBitCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst));
|
||||
case IrInstSrcIdPtrToInt:
|
||||
return destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst));
|
||||
case IrInstSrcIdIntToPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst));
|
||||
case IrInstSrcIdIntToEnum:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst));
|
||||
case IrInstSrcIdIntToErr:
|
||||
return destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst));
|
||||
case IrInstSrcIdErrToInt:
|
||||
return destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst));
|
||||
case IrInstSrcIdCheckSwitchProngs:
|
||||
return destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst));
|
||||
case IrInstSrcIdCheckStatementIsVoid:
|
||||
return destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst));
|
||||
case IrInstSrcIdTypeName:
|
||||
return destroy(reinterpret_cast<IrInstSrcTypeName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst));
|
||||
case IrInstSrcIdTagName:
|
||||
return destroy(reinterpret_cast<IrInstSrcTagName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst));
|
||||
case IrInstSrcIdPtrType:
|
||||
return destroy(reinterpret_cast<IrInstSrcPtrType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst));
|
||||
case IrInstSrcIdDeclRef:
|
||||
return destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst));
|
||||
case IrInstSrcIdPanic:
|
||||
return destroy(reinterpret_cast<IrInstSrcPanic *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst));
|
||||
case IrInstSrcIdFieldParentPtr:
|
||||
return destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst));
|
||||
case IrInstSrcIdByteOffsetOf:
|
||||
return destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst));
|
||||
case IrInstSrcIdBitOffsetOf:
|
||||
return destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst));
|
||||
case IrInstSrcIdTypeInfo:
|
||||
return destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst));
|
||||
case IrInstSrcIdType:
|
||||
return destroy(reinterpret_cast<IrInstSrcType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));
|
||||
case IrInstSrcIdHasField:
|
||||
return destroy(reinterpret_cast<IrInstSrcHasField *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));
|
||||
case IrInstSrcIdTypeId:
|
||||
return destroy(reinterpret_cast<IrInstSrcTypeId *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeId *>(inst));
|
||||
case IrInstSrcIdSetEvalBranchQuota:
|
||||
return destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));
|
||||
case IrInstSrcIdAlignCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst));
|
||||
case IrInstSrcIdImplicitCast:
|
||||
return destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst));
|
||||
case IrInstSrcIdResolveResult:
|
||||
return destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst));
|
||||
case IrInstSrcIdResetResult:
|
||||
return destroy(reinterpret_cast<IrInstSrcResetResult *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst));
|
||||
case IrInstSrcIdOpaqueType:
|
||||
return destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst));
|
||||
case IrInstSrcIdSetAlignStack:
|
||||
return destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst));
|
||||
case IrInstSrcIdArgType:
|
||||
return destroy(reinterpret_cast<IrInstSrcArgType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst));
|
||||
case IrInstSrcIdTagType:
|
||||
return destroy(reinterpret_cast<IrInstSrcTagType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagType *>(inst));
|
||||
case IrInstSrcIdExport:
|
||||
return destroy(reinterpret_cast<IrInstSrcExport *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst));
|
||||
case IrInstSrcIdErrorReturnTrace:
|
||||
return destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst));
|
||||
case IrInstSrcIdErrorUnion:
|
||||
return destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst));
|
||||
case IrInstSrcIdAtomicRmw:
|
||||
return destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst));
|
||||
case IrInstSrcIdSaveErrRetAddr:
|
||||
return destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst));
|
||||
case IrInstSrcIdAddImplicitReturnType:
|
||||
return destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst));
|
||||
case IrInstSrcIdFloatOp:
|
||||
return destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst));
|
||||
case IrInstSrcIdMulAdd:
|
||||
return destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst));
|
||||
case IrInstSrcIdAtomicLoad:
|
||||
return destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst));
|
||||
case IrInstSrcIdAtomicStore:
|
||||
return destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst));
|
||||
case IrInstSrcIdEnumToInt:
|
||||
return destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst));
|
||||
case IrInstSrcIdCheckRuntimeScope:
|
||||
return destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst));
|
||||
case IrInstSrcIdHasDecl:
|
||||
return destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst));
|
||||
case IrInstSrcIdUndeclaredIdent:
|
||||
return destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst));
|
||||
case IrInstSrcIdAlloca:
|
||||
return destroy(reinterpret_cast<IrInstSrcAlloca *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst));
|
||||
case IrInstSrcIdEndExpr:
|
||||
return destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst));
|
||||
case IrInstSrcIdUnionInitNamedField:
|
||||
return destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst));
|
||||
case IrInstSrcIdSuspendBegin:
|
||||
return destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst));
|
||||
case IrInstSrcIdSuspendFinish:
|
||||
return destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst));
|
||||
case IrInstSrcIdResume:
|
||||
return destroy(reinterpret_cast<IrInstSrcResume *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst));
|
||||
case IrInstSrcIdAwait:
|
||||
return destroy(reinterpret_cast<IrInstSrcAwait *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst));
|
||||
case IrInstSrcIdSpillBegin:
|
||||
return destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst));
|
||||
case IrInstSrcIdSpillEnd:
|
||||
return destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst));
|
||||
case IrInstSrcIdCallArgs:
|
||||
return destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst));
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
void destroy_instruction_gen(IrInstGen *inst) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
const char *name = ir_inst_gen_type_str(inst->id);
|
||||
#else
|
||||
const char *name = nullptr;
|
||||
#endif
|
||||
switch (inst->id) {
|
||||
case IrInstGenIdInvalid:
|
||||
zig_unreachable();
|
||||
case IrInstGenIdReturn:
|
||||
return destroy(reinterpret_cast<IrInstGenReturn *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturn *>(inst));
|
||||
case IrInstGenIdConst:
|
||||
return destroy(reinterpret_cast<IrInstGenConst *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenConst *>(inst));
|
||||
case IrInstGenIdBinOp:
|
||||
return destroy(reinterpret_cast<IrInstGenBinOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinOp *>(inst));
|
||||
case IrInstGenIdCast:
|
||||
return destroy(reinterpret_cast<IrInstGenCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCast *>(inst));
|
||||
case IrInstGenIdCall:
|
||||
return destroy(reinterpret_cast<IrInstGenCall *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCall *>(inst));
|
||||
case IrInstGenIdCondBr:
|
||||
return destroy(reinterpret_cast<IrInstGenCondBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCondBr *>(inst));
|
||||
case IrInstGenIdBr:
|
||||
return destroy(reinterpret_cast<IrInstGenBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBr *>(inst));
|
||||
case IrInstGenIdPhi:
|
||||
return destroy(reinterpret_cast<IrInstGenPhi *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPhi *>(inst));
|
||||
case IrInstGenIdUnreachable:
|
||||
return destroy(reinterpret_cast<IrInstGenUnreachable *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnreachable *>(inst));
|
||||
case IrInstGenIdElemPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenElemPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenElemPtr *>(inst));
|
||||
case IrInstGenIdVarPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenVarPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVarPtr *>(inst));
|
||||
case IrInstGenIdReturnPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst));
|
||||
case IrInstGenIdLoadPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst));
|
||||
case IrInstGenIdStorePtr:
|
||||
return destroy(reinterpret_cast<IrInstGenStorePtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStorePtr *>(inst));
|
||||
case IrInstGenIdVectorStoreElem:
|
||||
return destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst));
|
||||
case IrInstGenIdStructFieldPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst));
|
||||
case IrInstGenIdUnionFieldPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst));
|
||||
case IrInstGenIdAsm:
|
||||
return destroy(reinterpret_cast<IrInstGenAsm *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAsm *>(inst));
|
||||
case IrInstGenIdTestNonNull:
|
||||
return destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst));
|
||||
case IrInstGenIdOptionalUnwrapPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst));
|
||||
case IrInstGenIdPopCount:
|
||||
return destroy(reinterpret_cast<IrInstGenPopCount *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPopCount *>(inst));
|
||||
case IrInstGenIdClz:
|
||||
return destroy(reinterpret_cast<IrInstGenClz *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenClz *>(inst));
|
||||
case IrInstGenIdCtz:
|
||||
return destroy(reinterpret_cast<IrInstGenCtz *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCtz *>(inst));
|
||||
case IrInstGenIdBswap:
|
||||
return destroy(reinterpret_cast<IrInstGenBswap *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBswap *>(inst));
|
||||
case IrInstGenIdBitReverse:
|
||||
return destroy(reinterpret_cast<IrInstGenBitReverse *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitReverse *>(inst));
|
||||
case IrInstGenIdSwitchBr:
|
||||
return destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst));
|
||||
case IrInstGenIdUnionTag:
|
||||
return destroy(reinterpret_cast<IrInstGenUnionTag *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionTag *>(inst));
|
||||
case IrInstGenIdRef:
|
||||
return destroy(reinterpret_cast<IrInstGenRef *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenRef *>(inst));
|
||||
case IrInstGenIdErrName:
|
||||
return destroy(reinterpret_cast<IrInstGenErrName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrName *>(inst));
|
||||
case IrInstGenIdCmpxchg:
|
||||
return destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst));
|
||||
case IrInstGenIdFence:
|
||||
return destroy(reinterpret_cast<IrInstGenFence *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFence *>(inst));
|
||||
case IrInstGenIdTruncate:
|
||||
return destroy(reinterpret_cast<IrInstGenTruncate *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTruncate *>(inst));
|
||||
case IrInstGenIdShuffleVector:
|
||||
return destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst));
|
||||
case IrInstGenIdSplat:
|
||||
return destroy(reinterpret_cast<IrInstGenSplat *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSplat *>(inst));
|
||||
case IrInstGenIdBoolNot:
|
||||
return destroy(reinterpret_cast<IrInstGenBoolNot *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBoolNot *>(inst));
|
||||
case IrInstGenIdMemset:
|
||||
return destroy(reinterpret_cast<IrInstGenMemset *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemset *>(inst));
|
||||
case IrInstGenIdMemcpy:
|
||||
return destroy(reinterpret_cast<IrInstGenMemcpy *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemcpy *>(inst));
|
||||
case IrInstGenIdSlice:
|
||||
return destroy(reinterpret_cast<IrInstGenSlice *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSlice *>(inst));
|
||||
case IrInstGenIdBreakpoint:
|
||||
return destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst));
|
||||
case IrInstGenIdReturnAddress:
|
||||
return destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst));
|
||||
case IrInstGenIdFrameAddress:
|
||||
return destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst));
|
||||
case IrInstGenIdFrameHandle:
|
||||
return destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst));
|
||||
case IrInstGenIdFrameSize:
|
||||
return destroy(reinterpret_cast<IrInstGenFrameSize *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameSize *>(inst));
|
||||
case IrInstGenIdOverflowOp:
|
||||
return destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst));
|
||||
case IrInstGenIdTestErr:
|
||||
return destroy(reinterpret_cast<IrInstGenTestErr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestErr *>(inst));
|
||||
case IrInstGenIdUnwrapErrCode:
|
||||
return destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst));
|
||||
case IrInstGenIdUnwrapErrPayload:
|
||||
return destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst));
|
||||
case IrInstGenIdOptionalWrap:
|
||||
return destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst));
|
||||
case IrInstGenIdErrWrapCode:
|
||||
return destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst));
|
||||
case IrInstGenIdErrWrapPayload:
|
||||
return destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst));
|
||||
case IrInstGenIdPtrCast:
|
||||
return destroy(reinterpret_cast<IrInstGenPtrCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrCast *>(inst));
|
||||
case IrInstGenIdBitCast:
|
||||
return destroy(reinterpret_cast<IrInstGenBitCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitCast *>(inst));
|
||||
case IrInstGenIdWidenOrShorten:
|
||||
return destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst));
|
||||
case IrInstGenIdPtrToInt:
|
||||
return destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst));
|
||||
case IrInstGenIdIntToPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst));
|
||||
case IrInstGenIdIntToEnum:
|
||||
return destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst));
|
||||
case IrInstGenIdIntToErr:
|
||||
return destroy(reinterpret_cast<IrInstGenIntToErr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToErr *>(inst));
|
||||
case IrInstGenIdErrToInt:
|
||||
return destroy(reinterpret_cast<IrInstGenErrToInt *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrToInt *>(inst));
|
||||
case IrInstGenIdTagName:
|
||||
return destroy(reinterpret_cast<IrInstGenTagName *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTagName *>(inst));
|
||||
case IrInstGenIdPanic:
|
||||
return destroy(reinterpret_cast<IrInstGenPanic *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPanic *>(inst));
|
||||
case IrInstGenIdFieldParentPtr:
|
||||
return destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst));
|
||||
case IrInstGenIdAlignCast:
|
||||
return destroy(reinterpret_cast<IrInstGenAlignCast *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlignCast *>(inst));
|
||||
case IrInstGenIdErrorReturnTrace:
|
||||
return destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst));
|
||||
case IrInstGenIdAtomicRmw:
|
||||
return destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst));
|
||||
case IrInstGenIdSaveErrRetAddr:
|
||||
return destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst));
|
||||
case IrInstGenIdFloatOp:
|
||||
return destroy(reinterpret_cast<IrInstGenFloatOp *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFloatOp *>(inst));
|
||||
case IrInstGenIdMulAdd:
|
||||
return destroy(reinterpret_cast<IrInstGenMulAdd *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMulAdd *>(inst));
|
||||
case IrInstGenIdAtomicLoad:
|
||||
return destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst));
|
||||
case IrInstGenIdAtomicStore:
|
||||
return destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst));
|
||||
case IrInstGenIdDeclVar:
|
||||
return destroy(reinterpret_cast<IrInstGenDeclVar *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenDeclVar *>(inst));
|
||||
case IrInstGenIdArrayToVector:
|
||||
return destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst));
|
||||
case IrInstGenIdVectorToArray:
|
||||
return destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst));
|
||||
case IrInstGenIdPtrOfArrayToSlice:
|
||||
return destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst));
|
||||
case IrInstGenIdAssertZero:
|
||||
return destroy(reinterpret_cast<IrInstGenAssertZero *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));
|
||||
case IrInstGenIdAssertNonNull:
|
||||
return destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));
|
||||
case IrInstGenIdResizeSlice:
|
||||
return destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst));
|
||||
case IrInstGenIdAlloca:
|
||||
return destroy(reinterpret_cast<IrInstGenAlloca *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));
|
||||
case IrInstGenIdSuspendBegin:
|
||||
return destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst));
|
||||
case IrInstGenIdSuspendFinish:
|
||||
return destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst));
|
||||
case IrInstGenIdResume:
|
||||
return destroy(reinterpret_cast<IrInstGenResume *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResume *>(inst));
|
||||
case IrInstGenIdAwait:
|
||||
return destroy(reinterpret_cast<IrInstGenAwait *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAwait *>(inst));
|
||||
case IrInstGenIdSpillBegin:
|
||||
return destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst));
|
||||
case IrInstGenIdSpillEnd:
|
||||
return destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst));
|
||||
case IrInstGenIdVectorExtractElem:
|
||||
return destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst));
|
||||
case IrInstGenIdBinaryNot:
|
||||
return destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));
|
||||
case IrInstGenIdNegation:
|
||||
return destroy(reinterpret_cast<IrInstGenNegation *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));
|
||||
case IrInstGenIdNegationWrapping:
|
||||
return destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst), name);
|
||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst));
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@@ -760,34 +751,19 @@ static void ira_deref(IrAnalyze *ira) {
|
||||
IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i];
|
||||
destroy_instruction_src(pass1_inst);
|
||||
}
|
||||
destroy(pass1_bb, "IrBasicBlockSrc");
|
||||
heap::c_allocator.destroy(pass1_bb);
|
||||
}
|
||||
ira->old_irb.exec->basic_block_list.deinit();
|
||||
ira->old_irb.exec->tld_list.deinit();
|
||||
// cannot destroy here because of var->owner_exec
|
||||
//destroy(ira->old_irb.exec, "IrExecutableSrc");
|
||||
heap::c_allocator.destroy(ira->old_irb.exec);
|
||||
ira->src_implicit_return_type_list.deinit();
|
||||
ira->resume_stack.deinit();
|
||||
destroy(ira, "IrAnalyze");
|
||||
heap::c_allocator.destroy(ira);
|
||||
}
|
||||
|
||||
static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
|
||||
static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) {
|
||||
assert(get_src_ptr_type(const_val->type) != nullptr);
|
||||
assert(const_val->special == ConstValSpecialStatic);
|
||||
ZigValue *result;
|
||||
|
||||
InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field;
|
||||
if (isf != nullptr) {
|
||||
TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
|
||||
assert(field != nullptr);
|
||||
if (field->is_comptime) {
|
||||
assert(field->init_val != nullptr);
|
||||
return field->init_val;
|
||||
}
|
||||
assert(const_val->data.x_ptr.special == ConstPtrSpecialRef);
|
||||
ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee;
|
||||
return struct_val->data.x_struct.fields[field->src_index];
|
||||
}
|
||||
|
||||
switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
|
||||
case OnePossibleValueInvalid:
|
||||
@@ -798,6 +774,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
|
||||
break;
|
||||
}
|
||||
|
||||
ZigValue *result;
|
||||
switch (const_val->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
zig_unreachable();
|
||||
@@ -843,6 +820,26 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
|
||||
assert(get_src_ptr_type(const_val->type) != nullptr);
|
||||
assert(const_val->special == ConstValSpecialStatic);
|
||||
|
||||
InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field;
|
||||
if (isf != nullptr) {
|
||||
TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
|
||||
assert(field != nullptr);
|
||||
if (field->is_comptime) {
|
||||
assert(field->init_val != nullptr);
|
||||
return field->init_val;
|
||||
}
|
||||
ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val);
|
||||
assert(struct_val->type->id == ZigTypeIdStruct);
|
||||
return struct_val->data.x_struct.fields[field->src_index];
|
||||
}
|
||||
|
||||
return const_ptr_pointee_unchecked_no_isf(g, const_val);
|
||||
}
|
||||
|
||||
static bool is_tuple(ZigType *type) {
|
||||
return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple;
|
||||
}
|
||||
@@ -1010,8 +1007,8 @@ static void ir_ref_var(ZigVar *var) {
|
||||
static void create_result_ptr(CodeGen *codegen, ZigType *expected_type,
|
||||
ZigValue **out_result, ZigValue **out_result_ptr)
|
||||
{
|
||||
ZigValue *result = create_const_vals(1);
|
||||
ZigValue *result_ptr = create_const_vals(1);
|
||||
ZigValue *result = codegen->pass1_arena->create<ZigValue>();
|
||||
ZigValue *result_ptr = codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialUndef;
|
||||
result->type = expected_type;
|
||||
result_ptr->special = ConstValSpecialStatic;
|
||||
@@ -1043,14 +1040,11 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
|
||||
assert(result->special != ConstValSpecialRuntime);
|
||||
ZigType *res_type = result->data.x_type;
|
||||
|
||||
destroy(result_ptr, "ZigValue");
|
||||
destroy(result, "ZigValue");
|
||||
|
||||
return res_type;
|
||||
}
|
||||
|
||||
static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) {
|
||||
IrBasicBlockSrc *result = allocate<IrBasicBlockSrc>(1, "IrBasicBlockSrc");
|
||||
IrBasicBlockSrc *result = heap::c_allocator.create<IrBasicBlockSrc>();
|
||||
result->scope = scope;
|
||||
result->name_hint = name_hint;
|
||||
result->debug_id = exec_next_debug_id(irb->exec);
|
||||
@@ -1059,7 +1053,7 @@ static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, c
|
||||
}
|
||||
|
||||
static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) {
|
||||
IrBasicBlockGen *result = allocate<IrBasicBlockGen>(1, "IrBasicBlockGen");
|
||||
IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>();
|
||||
result->scope = scope;
|
||||
result->name_hint = name_hint;
|
||||
result->debug_id = exec_next_debug_id_gen(ira->new_irb.exec);
|
||||
@@ -1976,12 +1970,7 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) {
|
||||
|
||||
template<typename T>
|
||||
static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
|
||||
const char *name = nullptr;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
T *dummy = nullptr;
|
||||
name = ir_inst_src_type_str(ir_inst_id(dummy));
|
||||
#endif
|
||||
T *special_instruction = allocate<T>(1, name);
|
||||
T *special_instruction = heap::c_allocator.create<T>();
|
||||
special_instruction->base.id = ir_inst_id(special_instruction);
|
||||
special_instruction->base.base.scope = scope;
|
||||
special_instruction->base.base.source_node = source_node;
|
||||
@@ -1992,29 +1981,19 @@ static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source
|
||||
|
||||
template<typename T>
|
||||
static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
|
||||
const char *name = nullptr;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
T *dummy = nullptr;
|
||||
name = ir_inst_gen_type_str(ir_inst_id(dummy));
|
||||
#endif
|
||||
T *special_instruction = allocate<T>(1, name);
|
||||
T *special_instruction = heap::c_allocator.create<T>();
|
||||
special_instruction->base.id = ir_inst_id(special_instruction);
|
||||
special_instruction->base.base.scope = scope;
|
||||
special_instruction->base.base.source_node = source_node;
|
||||
special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec);
|
||||
special_instruction->base.owner_bb = irb->current_basic_block;
|
||||
special_instruction->base.value = allocate<ZigValue>(1, "ZigValue");
|
||||
special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
return special_instruction;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
|
||||
const char *name = nullptr;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
T *dummy = nullptr;
|
||||
name = ir_inst_gen_type_str(ir_inst_id(dummy));
|
||||
#endif
|
||||
T *special_instruction = allocate<T>(1, name);
|
||||
T *special_instruction = heap::c_allocator.create<T>();
|
||||
special_instruction->base.id = ir_inst_id(special_instruction);
|
||||
special_instruction->base.base.scope = scope;
|
||||
special_instruction->base.base.source_node = source_node;
|
||||
@@ -2056,11 +2035,11 @@ static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_no
|
||||
IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
|
||||
ZigType *var_type, const char *name_hint)
|
||||
{
|
||||
IrInstGenAlloca *alloca_gen = allocate<IrInstGenAlloca>(1);
|
||||
IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();
|
||||
alloca_gen->base.id = IrInstGenIdAlloca;
|
||||
alloca_gen->base.base.source_node = source_node;
|
||||
alloca_gen->base.base.scope = scope;
|
||||
alloca_gen->base.value = allocate<ZigValue>(1, "ZigValue");
|
||||
alloca_gen->base.value = g->pass1_arena->create<ZigValue>();
|
||||
alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false);
|
||||
alloca_gen->base.base.ref_count = 1;
|
||||
alloca_gen->name_hint = name_hint;
|
||||
@@ -2150,7 +2129,7 @@ static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstN
|
||||
|
||||
static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
|
||||
@@ -2159,7 +2138,7 @@ static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *
|
||||
|
||||
static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint);
|
||||
@@ -2168,7 +2147,7 @@ static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode
|
||||
|
||||
static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat);
|
||||
@@ -2184,7 +2163,7 @@ static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *
|
||||
|
||||
static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_usize;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
|
||||
@@ -2195,7 +2174,7 @@ static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode
|
||||
ZigType *type_entry)
|
||||
{
|
||||
IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_type;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
const_instruction->value->data.x_type = type_entry;
|
||||
@@ -2212,7 +2191,7 @@ static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *
|
||||
|
||||
static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_type;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
const_instruction->value->data.x_type = import;
|
||||
@@ -2221,7 +2200,7 @@ static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode
|
||||
|
||||
static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_bool;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
const_instruction->value->data.x_bool = value;
|
||||
@@ -2230,7 +2209,7 @@ static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *
|
||||
|
||||
static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal;
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
const_instruction->value->data.x_enum_literal = name;
|
||||
@@ -2239,7 +2218,7 @@ static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, A
|
||||
|
||||
static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) {
|
||||
IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
init_const_str_lit(irb->codegen, const_instruction->value, str);
|
||||
|
||||
return &const_instruction->base;
|
||||
@@ -5237,7 +5216,7 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
|
||||
switch (node->data.return_expr.kind) {
|
||||
case ReturnKindUnconditional:
|
||||
{
|
||||
ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn");
|
||||
ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
|
||||
result_loc_ret->base.id = ResultLocIdReturn;
|
||||
ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
|
||||
|
||||
@@ -5325,7 +5304,7 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
|
||||
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr));
|
||||
IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val,
|
||||
SpillIdRetErrCode);
|
||||
ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn");
|
||||
ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
|
||||
result_loc_ret->base.id = ResultLocIdReturn;
|
||||
ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
|
||||
ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base);
|
||||
@@ -5353,12 +5332,12 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
|
||||
Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime,
|
||||
bool skip_name_check)
|
||||
{
|
||||
ZigVar *variable_entry = allocate<ZigVar>(1, "ZigVar");
|
||||
ZigVar *variable_entry = heap::c_allocator.create<ZigVar>();
|
||||
variable_entry->parent_scope = parent_scope;
|
||||
variable_entry->shadowable = is_shadowable;
|
||||
variable_entry->is_comptime = is_comptime;
|
||||
variable_entry->src_arg_index = SIZE_MAX;
|
||||
variable_entry->const_value = create_const_vals(1);
|
||||
variable_entry->const_value = codegen->pass1_arena->create<ZigValue>();
|
||||
|
||||
if (is_comptime != nullptr) {
|
||||
is_comptime->base.ref_count += 1;
|
||||
@@ -5418,15 +5397,12 @@ static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf
|
||||
ZigVar *var = create_local_var(irb->codegen, node, scope,
|
||||
(is_underscored ? nullptr : name), src_is_const, gen_is_const,
|
||||
(is_underscored ? true : is_shadowable), is_comptime, false);
|
||||
if (is_comptime != nullptr || gen_is_const) {
|
||||
var->owner_exec = irb->exec;
|
||||
}
|
||||
assert(var->child_scope);
|
||||
return var;
|
||||
}
|
||||
|
||||
static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
|
||||
ResultLocPeer *result = allocate<ResultLocPeer>(1, "ResultLocPeer");
|
||||
ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>();
|
||||
result->base.id = ResultLocIdPeer;
|
||||
result->base.source_instruction = peer_parent->base.source_instruction;
|
||||
result->parent = peer_parent;
|
||||
@@ -5465,7 +5441,7 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||
scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node,
|
||||
ir_should_inline(irb->exec, parent_scope));
|
||||
|
||||
scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent");
|
||||
scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
|
||||
scope_block->peer_parent->base.id = ResultLocIdPeerParent;
|
||||
scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
|
||||
scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
|
||||
@@ -5555,7 +5531,7 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||
// only generate unconditional defers
|
||||
|
||||
ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr));
|
||||
ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn");
|
||||
ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
|
||||
result_loc_ret->base.id = ResultLocIdReturn;
|
||||
ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base);
|
||||
ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base));
|
||||
@@ -5597,7 +5573,7 @@ static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node)
|
||||
if (lvalue == irb->codegen->invalid_inst_src)
|
||||
return irb->codegen->invalid_inst_src;
|
||||
|
||||
ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1, "ResultLocInstruction");
|
||||
ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
|
||||
result_loc_inst->base.id = ResultLocIdInstruction;
|
||||
result_loc_inst->base.source_instruction = lvalue;
|
||||
ir_ref_instruction(lvalue, irb->current_basic_block);
|
||||
@@ -5669,10 +5645,10 @@ static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node)
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, true_block);
|
||||
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2, "IrInstSrc *");
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = val1;
|
||||
incoming_values[1] = val2;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = post_val1_block;
|
||||
incoming_blocks[1] = post_val2_block;
|
||||
|
||||
@@ -5711,10 +5687,10 @@ static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, false_block);
|
||||
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = val1;
|
||||
incoming_values[1] = val2;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = post_val1_block;
|
||||
incoming_blocks[1] = post_val2_block;
|
||||
|
||||
@@ -5724,7 +5700,7 @@ static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node
|
||||
static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst,
|
||||
IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime)
|
||||
{
|
||||
ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
|
||||
ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
|
||||
peer_parent->base.id = ResultLocIdPeerParent;
|
||||
peer_parent->base.source_instruction = cond_br_inst;
|
||||
peer_parent->base.allow_write_through_const = parent->allow_write_through_const;
|
||||
@@ -5802,10 +5778,10 @@ static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode
|
||||
ir_build_br(irb, parent_scope, node, end_block, is_comptime);
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, end_block);
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = null_result;
|
||||
incoming_values[1] = unwrapped_payload;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = after_null_block;
|
||||
incoming_blocks[1] = after_ok_block;
|
||||
IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
|
||||
@@ -5959,7 +5935,7 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode
|
||||
}
|
||||
scope = scope->parent;
|
||||
}
|
||||
TldVar *tld_var = allocate<TldVar>(1);
|
||||
TldVar *tld_var = heap::c_allocator.create<TldVar>();
|
||||
init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
|
||||
tld_var->base.resolution = TldResolutionInvalid;
|
||||
tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
|
||||
@@ -5976,7 +5952,7 @@ static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node,
|
||||
if (buf_eql_str(variable_name, "_")) {
|
||||
if (lval == LValPtr) {
|
||||
IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node);
|
||||
const_instruction->value = create_const_vals(1);
|
||||
const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
|
||||
const_instruction->value->type = get_pointer_to_type(irb->codegen,
|
||||
irb->codegen->builtin_types.entry_void, false);
|
||||
const_instruction->value->special = ConstValSpecialStatic;
|
||||
@@ -6170,7 +6146,7 @@ static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *aw
|
||||
return fn_ref;
|
||||
|
||||
size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset;
|
||||
IrInstSrc **args = allocate<IrInstSrc*>(arg_count);
|
||||
IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
|
||||
for (size_t i = 0; i < arg_count; i += 1) {
|
||||
AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset);
|
||||
IrInstSrc *arg = ir_gen_node(irb, arg_node, scope);
|
||||
@@ -6196,7 +6172,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN
|
||||
|
||||
IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref);
|
||||
|
||||
IrInstSrc **args = allocate<IrInstSrc*>(args_len);
|
||||
IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
|
||||
for (size_t i = 0; i < args_len; i += 1) {
|
||||
AstNode *arg_node = args_ptr[i];
|
||||
|
||||
@@ -6381,7 +6357,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||
}
|
||||
case BuiltinFnIdCompileLog:
|
||||
{
|
||||
IrInstSrc **args = allocate<IrInstSrc*>(actual_param_count);
|
||||
IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count);
|
||||
|
||||
for (size_t i = 0; i < actual_param_count; i += 1) {
|
||||
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
|
||||
@@ -7006,7 +6982,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||
if (dest_type == irb->codegen->invalid_inst_src)
|
||||
return dest_type;
|
||||
|
||||
ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1);
|
||||
ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>();
|
||||
result_loc_bit_cast->base.id = ResultLocIdBitCast;
|
||||
result_loc_bit_cast->base.source_instruction = dest_type;
|
||||
result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const;
|
||||
@@ -7555,10 +7531,10 @@ static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *
|
||||
ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, endif_block);
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = then_expr_result;
|
||||
incoming_values[1] = else_expr_result;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = after_then_block;
|
||||
incoming_blocks[1] = after_else_block;
|
||||
|
||||
@@ -7759,7 +7735,7 @@ static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||
IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr,
|
||||
field_name, true);
|
||||
|
||||
ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
|
||||
ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
|
||||
result_loc_inst->base.id = ResultLocIdInstruction;
|
||||
result_loc_inst->base.source_instruction = field_ptr;
|
||||
ir_ref_instruction(field_ptr, irb->current_basic_block);
|
||||
@@ -7835,7 +7811,7 @@ static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, As
|
||||
nullptr);
|
||||
|
||||
size_t field_count = container_init_expr->entries.length;
|
||||
IrInstSrcContainerInitFieldsField *fields = allocate<IrInstSrcContainerInitFieldsField>(field_count);
|
||||
IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count);
|
||||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
AstNode *entry_node = container_init_expr->entries.at(i);
|
||||
assert(entry_node->type == NodeTypeStructValueField);
|
||||
@@ -7844,7 +7820,7 @@ static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, As
|
||||
AstNode *expr_node = entry_node->data.struct_val_field.expr;
|
||||
|
||||
IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true);
|
||||
ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
|
||||
ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
|
||||
result_loc_inst->base.id = ResultLocIdInstruction;
|
||||
result_loc_inst->base.source_instruction = field_ptr;
|
||||
result_loc_inst->base.allow_write_through_const = true;
|
||||
@@ -7874,14 +7850,14 @@ static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, As
|
||||
IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
|
||||
nullptr);
|
||||
|
||||
IrInstSrc **result_locs = allocate<IrInstSrc *>(item_count);
|
||||
IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count);
|
||||
for (size_t i = 0; i < item_count; i += 1) {
|
||||
AstNode *expr_node = container_init_expr->entries.at(i);
|
||||
|
||||
IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
|
||||
IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr,
|
||||
elem_index, false, PtrLenSingle, init_array_type_source_node);
|
||||
ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
|
||||
ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
|
||||
result_loc_inst->base.id = ResultLocIdInstruction;
|
||||
result_loc_inst->base.source_instruction = elem_ptr;
|
||||
result_loc_inst->base.allow_write_through_const = true;
|
||||
@@ -7907,7 +7883,7 @@ static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, As
|
||||
}
|
||||
|
||||
static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) {
|
||||
ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
|
||||
ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>();
|
||||
result_loc_var->base.id = ResultLocIdVar;
|
||||
result_loc_var->base.source_instruction = alloca;
|
||||
result_loc_var->base.allow_write_through_const = true;
|
||||
@@ -7921,7 +7897,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloc
|
||||
static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type,
|
||||
ResultLoc *parent_result_loc)
|
||||
{
|
||||
ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1);
|
||||
ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>();
|
||||
result_loc_cast->base.id = ResultLocIdCast;
|
||||
result_loc_cast->base.source_instruction = dest_type;
|
||||
result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const;
|
||||
@@ -8764,9 +8740,9 @@ static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node
|
||||
nullptr, 0, is_volatile, true);
|
||||
}
|
||||
|
||||
IrInstSrc **input_list = allocate<IrInstSrc *>(asm_expr->input_list.length);
|
||||
IrInstSrc **output_types = allocate<IrInstSrc *>(asm_expr->output_list.length);
|
||||
ZigVar **output_vars = allocate<ZigVar *>(asm_expr->output_list.length);
|
||||
IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length);
|
||||
IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length);
|
||||
ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length);
|
||||
size_t return_count = 0;
|
||||
if (!is_volatile && asm_expr->output_list.length == 0) {
|
||||
add_node_error(irb->codegen, node,
|
||||
@@ -8900,10 +8876,10 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo
|
||||
ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, endif_block);
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = then_expr_result;
|
||||
incoming_values[1] = else_expr_result;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = after_then_block;
|
||||
incoming_blocks[1] = after_else_block;
|
||||
|
||||
@@ -8997,10 +8973,10 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
|
||||
ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, endif_block);
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = then_expr_result;
|
||||
incoming_values[1] = else_expr_result;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = after_then_block;
|
||||
incoming_blocks[1] = after_else_block;
|
||||
|
||||
@@ -9093,7 +9069,7 @@ static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
|
||||
|
||||
IrInstSrcSwitchElseVar *switch_else_var = nullptr;
|
||||
|
||||
ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
|
||||
ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
|
||||
peer_parent->base.id = ResultLocIdPeerParent;
|
||||
peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
|
||||
peer_parent->end_bb = end_block;
|
||||
@@ -9255,7 +9231,7 @@ static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
|
||||
ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
|
||||
|
||||
IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");
|
||||
IrInstSrc **items = allocate<IrInstSrc *>(prong_item_count);
|
||||
IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count);
|
||||
|
||||
for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
|
||||
AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
|
||||
@@ -9637,10 +9613,10 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||
ir_build_br(irb, parent_scope, node, end_block, is_comptime);
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, end_block);
|
||||
IrInstSrc **incoming_values = allocate<IrInstSrc *>(2);
|
||||
IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
|
||||
incoming_values[0] = err_result;
|
||||
incoming_values[1] = unwrapped_payload;
|
||||
IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *");
|
||||
IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
|
||||
incoming_blocks[0] = after_err_block;
|
||||
incoming_blocks[1] = after_ok_block;
|
||||
IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
|
||||
@@ -9707,7 +9683,7 @@ static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope,
|
||||
scan_decls(irb->codegen, child_scope, child_node);
|
||||
}
|
||||
|
||||
TldContainer *tld_container = allocate<TldContainer>(1);
|
||||
TldContainer *tld_container = heap::c_allocator.create<TldContainer>();
|
||||
init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope);
|
||||
tld_container->type_entry = container_type;
|
||||
tld_container->decls_scope = child_scope;
|
||||
@@ -9750,7 +9726,7 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp
|
||||
}
|
||||
|
||||
err_set_type->data.error_set.err_count = count;
|
||||
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count);
|
||||
err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count);
|
||||
|
||||
bool need_comma = false;
|
||||
for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) {
|
||||
@@ -9797,7 +9773,7 @@ static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstN
|
||||
err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align;
|
||||
err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size;
|
||||
err_set_type->data.error_set.err_count = 1;
|
||||
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1);
|
||||
err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>();
|
||||
|
||||
err_set_type->data.error_set.errors[0] = err_entry;
|
||||
|
||||
@@ -9828,16 +9804,16 @@ static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, As
|
||||
err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits;
|
||||
err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align;
|
||||
err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size;
|
||||
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count);
|
||||
err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count);
|
||||
|
||||
size_t errors_count = irb->codegen->errors_by_index.length + err_count;
|
||||
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *");
|
||||
ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
|
||||
|
||||
for (uint32_t i = 0; i < err_count; i += 1) {
|
||||
AstNode *field_node = node->data.err_set_decl.decls.at(i);
|
||||
AstNode *symbol_node = ast_field_to_symbol_node(field_node);
|
||||
Buf *err_name = symbol_node->data.symbol_expr.symbol;
|
||||
ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
|
||||
ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>();
|
||||
err->decl_node = field_node;
|
||||
buf_init_from_buf(&err->name, err_name);
|
||||
|
||||
@@ -9862,7 +9838,7 @@ static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, As
|
||||
}
|
||||
errors[err->value] = err;
|
||||
}
|
||||
deallocate(errors, errors_count, "ErrorTableEntry *");
|
||||
heap::c_allocator.deallocate(errors, errors_count);
|
||||
return ir_build_const_type(irb, parent_scope, node, err_set_type);
|
||||
}
|
||||
|
||||
@@ -9870,7 +9846,7 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
|
||||
assert(node->type == NodeTypeFnProto);
|
||||
|
||||
size_t param_count = node->data.fn_proto.params.length;
|
||||
IrInstSrc **param_types = allocate<IrInstSrc*>(param_count);
|
||||
IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count);
|
||||
|
||||
bool is_var_args = false;
|
||||
for (size_t i = 0; i < param_count; i += 1) {
|
||||
@@ -10151,7 +10127,7 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
|
||||
}
|
||||
|
||||
static ResultLoc *no_result_loc(void) {
|
||||
ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
|
||||
ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>();
|
||||
result_loc_none->base.id = ResultLocIdNone;
|
||||
return &result_loc_none->base;
|
||||
}
|
||||
@@ -10240,7 +10216,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_e
|
||||
if (!instr_is_unreachable(result)) {
|
||||
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr));
|
||||
// no need for save_err_ret_addr because this cannot return error
|
||||
ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn");
|
||||
ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
|
||||
result_loc_ret->base.id = ResultLocIdReturn;
|
||||
ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
|
||||
ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base));
|
||||
@@ -10332,7 +10308,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast
|
||||
if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val)))
|
||||
return err;
|
||||
ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val);
|
||||
copy_const_val(child_val, &tmp);
|
||||
copy_const_val(codegen, child_val, &tmp);
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
@@ -11482,7 +11458,7 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp
|
||||
return set1;
|
||||
}
|
||||
size_t errors_count = ira->codegen->errors_by_index.length;
|
||||
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *");
|
||||
ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
|
||||
populate_error_set_table(errors, set1);
|
||||
ZigList<ErrorTableEntry *> intersection_list = {};
|
||||
|
||||
@@ -11503,7 +11479,7 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp
|
||||
buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&existing_entry_with_docs->name));
|
||||
}
|
||||
}
|
||||
deallocate(errors, errors_count, "ErrorTableEntry *");
|
||||
heap::c_allocator.deallocate(errors, errors_count);
|
||||
|
||||
err_set_type->data.error_set.err_count = intersection_list.length;
|
||||
err_set_type->data.error_set.errors = intersection_list.items;
|
||||
@@ -11552,10 +11528,11 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
wanted_ptr_type->data.pointer.sentinel == nullptr ||
|
||||
(actual_ptr_type->data.pointer.sentinel != nullptr &&
|
||||
const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel,
|
||||
actual_ptr_type->data.pointer.sentinel));
|
||||
actual_ptr_type->data.pointer.sentinel)) ||
|
||||
actual_ptr_type->data.pointer.ptr_len == PtrLenC;
|
||||
if (!ok_null_term_ptrs) {
|
||||
result.id = ConstCastResultIdPtrSentinel;
|
||||
result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
|
||||
result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1);
|
||||
result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type;
|
||||
result.data.bad_ptr_sentinel->actual_type = actual_ptr_type;
|
||||
return result;
|
||||
@@ -11571,7 +11548,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile);
|
||||
if (!ok_cv_qualifiers) {
|
||||
result.id = ConstCastResultIdCV;
|
||||
result.data.bad_cv = allocate_nonzero<ConstCastBadCV>(1);
|
||||
result.data.bad_cv = heap::c_allocator.allocate_nonzero<ConstCastBadCV>(1);
|
||||
result.data.bad_cv->wanted_type = wanted_ptr_type;
|
||||
result.data.bad_cv->actual_type = actual_ptr_type;
|
||||
return result;
|
||||
@@ -11583,7 +11560,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdPointerChild;
|
||||
result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1);
|
||||
result.data.pointer_mismatch = heap::c_allocator.allocate_nonzero<ConstCastPointerMismatch>(1);
|
||||
result.data.pointer_mismatch->child = child;
|
||||
result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type;
|
||||
result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
|
||||
@@ -11594,7 +11571,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
(!wanted_allows_zero && !actual_allows_zero);
|
||||
if (!ok_allows_zero) {
|
||||
result.id = ConstCastResultIdBadAllowsZero;
|
||||
result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1);
|
||||
result.data.bad_allows_zero = heap::c_allocator.allocate_nonzero<ConstCastBadAllowsZero>(1);
|
||||
result.data.bad_allows_zero->wanted_type = wanted_type;
|
||||
result.data.bad_allows_zero->actual_type = actual_type;
|
||||
return result;
|
||||
@@ -11634,7 +11611,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdArrayChild;
|
||||
result.data.array_mismatch = allocate_nonzero<ConstCastArrayMismatch>(1);
|
||||
result.data.array_mismatch = heap::c_allocator.allocate_nonzero<ConstCastArrayMismatch>(1);
|
||||
result.data.array_mismatch->child = child;
|
||||
result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type;
|
||||
result.data.array_mismatch->actual_child = actual_type->data.array.child_type;
|
||||
@@ -11645,7 +11622,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel));
|
||||
if (!ok_null_terminated) {
|
||||
result.id = ConstCastResultIdSentinelArrays;
|
||||
result.data.sentinel_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1);
|
||||
result.data.sentinel_arrays = heap::c_allocator.allocate_nonzero<ConstCastBadNullTermArrays>(1);
|
||||
result.data.sentinel_arrays->child = child;
|
||||
result.data.sentinel_arrays->wanted_type = wanted_type;
|
||||
result.data.sentinel_arrays->actual_type = actual_type;
|
||||
@@ -11673,7 +11650,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
actual_ptr_type->data.pointer.sentinel));
|
||||
if (!ok_sentinels) {
|
||||
result.id = ConstCastResultIdPtrSentinel;
|
||||
result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
|
||||
result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1);
|
||||
result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type;
|
||||
result.data.bad_ptr_sentinel->actual_type = actual_ptr_type;
|
||||
return result;
|
||||
@@ -11690,7 +11667,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdSliceChild;
|
||||
result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1);
|
||||
result.data.slice_mismatch = heap::c_allocator.allocate_nonzero<ConstCastSliceMismatch>(1);
|
||||
result.data.slice_mismatch->child = child;
|
||||
result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
|
||||
result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type;
|
||||
@@ -11707,7 +11684,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdOptionalChild;
|
||||
result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1);
|
||||
result.data.optional = heap::c_allocator.allocate_nonzero<ConstCastOptionalMismatch>(1);
|
||||
result.data.optional->child = child;
|
||||
result.data.optional->wanted_child = wanted_type->data.maybe.child_type;
|
||||
result.data.optional->actual_child = actual_type->data.maybe.child_type;
|
||||
@@ -11723,7 +11700,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return payload_child;
|
||||
if (payload_child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdErrorUnionPayload;
|
||||
result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1);
|
||||
result.data.error_union_payload = heap::c_allocator.allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1);
|
||||
result.data.error_union_payload->child = payload_child;
|
||||
result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type;
|
||||
result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type;
|
||||
@@ -11735,7 +11712,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return error_set_child;
|
||||
if (error_set_child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdErrorUnionErrorSet;
|
||||
result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1);
|
||||
result.data.error_union_error_set = heap::c_allocator.allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1);
|
||||
result.data.error_union_error_set->child = error_set_child;
|
||||
result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type;
|
||||
result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type;
|
||||
@@ -11769,7 +11746,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
}
|
||||
|
||||
size_t errors_count = g->errors_by_index.length;
|
||||
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *");
|
||||
ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
|
||||
for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) {
|
||||
ErrorTableEntry *error_entry = container_set->data.error_set.errors[i];
|
||||
assert(errors[error_entry->value] == nullptr);
|
||||
@@ -11781,12 +11758,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
if (error_entry == nullptr) {
|
||||
if (result.id == ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdErrSet;
|
||||
result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1);
|
||||
result.data.error_set_mismatch = heap::c_allocator.create<ConstCastErrSetMismatch>();
|
||||
}
|
||||
result.data.error_set_mismatch->missing_errors.append(contained_error_entry);
|
||||
}
|
||||
}
|
||||
deallocate(errors, errors_count, "ErrorTableEntry *");
|
||||
heap::c_allocator.deallocate(errors, errors_count);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -11815,7 +11792,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdFnReturnType;
|
||||
result.data.return_type = allocate_nonzero<ConstCastOnly>(1);
|
||||
result.data.return_type = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1);
|
||||
*result.data.return_type = child;
|
||||
return result;
|
||||
}
|
||||
@@ -11844,7 +11821,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
result.data.fn_arg.arg_index = i;
|
||||
result.data.fn_arg.actual_param_type = actual_param_info->type;
|
||||
result.data.fn_arg.expected_param_type = expected_param_info->type;
|
||||
result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1);
|
||||
result.data.fn_arg.child = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1);
|
||||
*result.data.fn_arg.child = arg_child;
|
||||
return result;
|
||||
}
|
||||
@@ -11864,15 +11841,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
}
|
||||
|
||||
if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) {
|
||||
result.id = ConstCastResultIdIntShorten;
|
||||
result.data.int_shorten = allocate_nonzero<ConstCastIntShorten>(1);
|
||||
result.data.int_shorten->wanted_type = wanted_type;
|
||||
result.data.int_shorten->actual_type = actual_type;
|
||||
if (wanted_type->data.integral.is_signed != actual_type->data.integral.is_signed ||
|
||||
wanted_type->data.integral.bit_count != actual_type->data.integral.bit_count)
|
||||
{
|
||||
result.id = ConstCastResultIdIntShorten;
|
||||
result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1);
|
||||
result.data.int_shorten->wanted_type = wanted_type;
|
||||
result.data.int_shorten->actual_type = actual_type;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
result.id = ConstCastResultIdType;
|
||||
result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1);
|
||||
result.data.type_mismatch = heap::c_allocator.allocate_nonzero<ConstCastTypeMismatch>(1);
|
||||
result.data.type_mismatch->wanted_type = wanted_type;
|
||||
result.data.type_mismatch->actual_type = actual_type;
|
||||
return result;
|
||||
@@ -11881,7 +11863,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) {
|
||||
size_t old_errors_count = *errors_count;
|
||||
*errors_count = g->errors_by_index.length;
|
||||
*errors = reallocate(*errors, old_errors_count, *errors_count);
|
||||
*errors = heap::c_allocator.reallocate(*errors, old_errors_count, *errors_count);
|
||||
}
|
||||
|
||||
static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type,
|
||||
@@ -12551,7 +12533,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
free(errors);
|
||||
heap::c_allocator.deallocate(errors, errors_count);
|
||||
|
||||
if (convert_to_const_slice) {
|
||||
if (prev_inst->value->type->id == ZigTypeIdPointer) {
|
||||
@@ -12630,7 +12612,7 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
|
||||
case CastOpBitCast:
|
||||
zig_panic("TODO");
|
||||
case CastOpNoop: {
|
||||
copy_const_val(const_val, other_val);
|
||||
copy_const_val(ira->codegen, const_val, other_val);
|
||||
const_val->type = new_type;
|
||||
break;
|
||||
}
|
||||
@@ -12770,13 +12752,19 @@ static IrInstGen *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrI
|
||||
wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type));
|
||||
|
||||
if (instr_is_comptime(value)) {
|
||||
ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, value->value, source_instr->source_node);
|
||||
ZigValue *val = ir_resolve_const(ira, value, UndefOk);
|
||||
if (val == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (val->special == ConstValSpecialUndef)
|
||||
return ir_const_undef(ira, source_instr, wanted_type);
|
||||
|
||||
ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
|
||||
if (pointee == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (pointee->special != ConstValSpecialRuntime) {
|
||||
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
|
||||
result->value->data.x_ptr.special = ConstPtrSpecialBaseArray;
|
||||
result->value->data.x_ptr.mut = value->value->data.x_ptr.mut;
|
||||
result->value->data.x_ptr.mut = val->data.x_ptr.mut;
|
||||
result->value->data.x_ptr.data.base_array.array_val = pointee;
|
||||
result->value->data.x_ptr.data.base_array.elem_index = 0;
|
||||
return result;
|
||||
@@ -13159,7 +13147,7 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
|
||||
if (type_is_invalid(return_ptr->type))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
||||
IrExecutableSrc *ir_executable = allocate<IrExecutableSrc>(1, "IrExecutableSrc");
|
||||
IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>();
|
||||
ir_executable->source_node = source_node;
|
||||
ir_executable->parent_exec = parent_exec;
|
||||
ir_executable->name = exec_name;
|
||||
@@ -13183,7 +13171,7 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
|
||||
ir_print_src(codegen, stderr, ir_executable, 2);
|
||||
fprintf(stderr, "}\n");
|
||||
}
|
||||
IrExecutableGen *analyzed_executable = allocate<IrExecutableGen>(1, "IrExecutableGen");
|
||||
IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>();
|
||||
analyzed_executable->source_node = source_node;
|
||||
analyzed_executable->parent_exec = parent_exec;
|
||||
analyzed_executable->source_exec = ir_executable;
|
||||
@@ -13384,7 +13372,7 @@ static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr,
|
||||
source_instr->scope, source_instr->source_node);
|
||||
const_instruction->base.value->special = ConstValSpecialStatic;
|
||||
if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) {
|
||||
copy_const_val(const_instruction->base.value, val);
|
||||
copy_const_val(ira->codegen, const_instruction->base.value, val);
|
||||
} else {
|
||||
const_instruction->base.value->data.x_optional = val;
|
||||
}
|
||||
@@ -13425,7 +13413,7 @@ static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_ins
|
||||
if (val == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
ZigValue *err_set_val = create_const_vals(1);
|
||||
ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
err_set_val->type = err_set_type;
|
||||
err_set_val->special = ConstValSpecialStatic;
|
||||
err_set_val->data.x_err_set = nullptr;
|
||||
@@ -13537,7 +13525,7 @@ static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr,
|
||||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
ZigValue *err_set_val = create_const_vals(1);
|
||||
ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
err_set_val->special = ConstValSpecialStatic;
|
||||
err_set_val->type = wanted_type->data.error_union.err_set_type;
|
||||
err_set_val->data.x_err_set = val->data.x_err_set;
|
||||
@@ -13802,7 +13790,7 @@ static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr,
|
||||
result->value->special = ConstValSpecialStatic;
|
||||
result->value->type = wanted_type;
|
||||
bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag);
|
||||
result->value->data.x_union.payload = create_const_vals(1);
|
||||
result->value->data.x_union.payload = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->value->data.x_union.payload->special = ConstValSpecialStatic;
|
||||
result->value->data.x_union.payload->type = field_type;
|
||||
return result;
|
||||
@@ -14107,7 +14095,7 @@ static IrInstGen *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInst* source_instr,
|
||||
if (pointee == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (pointee->special != ConstValSpecialRuntime) {
|
||||
ZigValue *array_val = create_const_vals(1);
|
||||
ZigValue *array_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
array_val->special = ConstValSpecialStatic;
|
||||
array_val->type = array_type;
|
||||
array_val->data.x_array.special = ConstArraySpecialNone;
|
||||
@@ -14321,7 +14309,7 @@ static IrInstGen *ir_analyze_array_to_vector(IrAnalyze *ira, IrInst* source_inst
|
||||
if (instr_is_comptime(array)) {
|
||||
// arrays and vectors have the same ZigValue representation
|
||||
IrInstGen *result = ir_const(ira, source_instr, vector_type);
|
||||
copy_const_val(result->value, array->value);
|
||||
copy_const_val(ira->codegen, result->value, array->value);
|
||||
result->value->type = vector_type;
|
||||
return result;
|
||||
}
|
||||
@@ -14334,7 +14322,7 @@ static IrInstGen *ir_analyze_vector_to_array(IrAnalyze *ira, IrInst* source_inst
|
||||
if (instr_is_comptime(vector)) {
|
||||
// arrays and vectors have the same ZigValue representation
|
||||
IrInstGen *result = ir_const(ira, source_instr, array_type);
|
||||
copy_const_val(result->value, vector->value);
|
||||
copy_const_val(ira->codegen, result->value, vector->value);
|
||||
result->value->type = array_type;
|
||||
return result;
|
||||
}
|
||||
@@ -14634,7 +14622,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
|
||||
if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) {
|
||||
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
|
||||
if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) {
|
||||
copy_const_val(result->value, value->value);
|
||||
copy_const_val(ira->codegen, result->value, value->value);
|
||||
result->value->type = wanted_type;
|
||||
} else {
|
||||
float_init_bigint(&result->value->data.x_bigint, value->value);
|
||||
@@ -14826,6 +14814,16 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
|
||||
}
|
||||
}
|
||||
|
||||
// @Vector(N,T1) to @Vector(N,T2)
|
||||
if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) {
|
||||
if (actual_type->data.vector.len == wanted_type->data.vector.len &&
|
||||
types_match_const_cast_only(ira, wanted_type->data.vector.elem_type,
|
||||
actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
|
||||
{
|
||||
return ir_analyze_bit_cast(ira, source_instr, value, wanted_type);
|
||||
}
|
||||
}
|
||||
|
||||
// *@Frame(func) to anyframe->T or anyframe
|
||||
// *@Frame(func) to ?anyframe->T or ?anyframe
|
||||
// *@Frame(func) to E!anyframe->T or E!anyframe
|
||||
@@ -16395,9 +16393,11 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
|
||||
case ZigTypeIdComptimeInt:
|
||||
case ZigTypeIdInt:
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdVector:
|
||||
zig_unreachable(); // handled with the type_is_numeric checks above
|
||||
|
||||
case ZigTypeIdVector:
|
||||
// Not every case is handled by the type_is_numeric checks above,
|
||||
// vectors of bool trigger this code path
|
||||
case ZigTypeIdBool:
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdVoid:
|
||||
@@ -16467,7 +16467,7 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
|
||||
IrInstGen *result = ir_const(ira, &bin_op_instruction->base.base,
|
||||
get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool));
|
||||
result->value->data.x_array.data.s_none.elements =
|
||||
create_const_vals(resolved_type->data.vector.len);
|
||||
ira->codegen->pass1_arena->allocate<ZigValue>(resolved_type->data.vector.len);
|
||||
|
||||
expand_undef_array(ira->codegen, result->value);
|
||||
for (size_t i = 0;i < resolved_type->data.vector.len;i++) {
|
||||
@@ -16475,7 +16475,7 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
|
||||
&op1_val->data.x_array.data.s_none.elements[i],
|
||||
&op2_val->data.x_array.data.s_none.elements[i],
|
||||
bin_op_instruction, op_id, one_possible_value);
|
||||
copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value);
|
||||
copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], cur_res->value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -17375,7 +17375,7 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi
|
||||
ZigValue *out_array_val;
|
||||
size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index);
|
||||
if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) {
|
||||
out_array_val = create_const_vals(1);
|
||||
out_array_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
out_array_val->special = ConstValSpecialStatic;
|
||||
out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel);
|
||||
|
||||
@@ -17387,11 +17387,11 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi
|
||||
true, false, PtrLenUnknown, 0, 0, 0, false,
|
||||
VECTOR_INDEX_NONE, nullptr, sentinel);
|
||||
result->value->type = get_slice_type(ira->codegen, ptr_type);
|
||||
out_array_val = create_const_vals(1);
|
||||
out_array_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
out_array_val->special = ConstValSpecialStatic;
|
||||
out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel);
|
||||
|
||||
out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
|
||||
out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
|
||||
out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type;
|
||||
out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic;
|
||||
@@ -17408,7 +17408,7 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi
|
||||
} else {
|
||||
result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown,
|
||||
0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel);
|
||||
out_array_val = create_const_vals(1);
|
||||
out_array_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
out_array_val->special = ConstValSpecialStatic;
|
||||
out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel);
|
||||
out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
|
||||
@@ -17424,7 +17424,7 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi
|
||||
}
|
||||
|
||||
uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0);
|
||||
out_array_val->data.x_array.data.s_none.elements = create_const_vals(full_len);
|
||||
out_array_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(full_len);
|
||||
// TODO handle the buf case here for an optimization
|
||||
expand_undef_array(ira->codegen, op1_array_val);
|
||||
expand_undef_array(ira->codegen, op2_array_val);
|
||||
@@ -17432,21 +17432,21 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi
|
||||
size_t next_index = 0;
|
||||
for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
|
||||
ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index];
|
||||
copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]);
|
||||
copy_const_val(ira->codegen, elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]);
|
||||
elem_dest_val->parent.id = ConstParentIdArray;
|
||||
elem_dest_val->parent.data.p_array.array_val = out_array_val;
|
||||
elem_dest_val->parent.data.p_array.elem_index = next_index;
|
||||
}
|
||||
for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
|
||||
ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index];
|
||||
copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]);
|
||||
copy_const_val(ira->codegen, elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]);
|
||||
elem_dest_val->parent.id = ConstParentIdArray;
|
||||
elem_dest_val->parent.data.p_array.array_val = out_array_val;
|
||||
elem_dest_val->parent.data.p_array.elem_index = next_index;
|
||||
}
|
||||
if (next_index < full_len) {
|
||||
ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index];
|
||||
copy_const_val(elem_dest_val, sentinel);
|
||||
copy_const_val(ira->codegen, elem_dest_val, sentinel);
|
||||
elem_dest_val->parent.id = ConstParentIdArray;
|
||||
elem_dest_val->parent.data.p_array.array_val = out_array_val;
|
||||
elem_dest_val->parent.data.p_array.elem_index = next_index;
|
||||
@@ -17525,13 +17525,13 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct
|
||||
// TODO optimize the buf case
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0;
|
||||
out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term);
|
||||
out_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(new_array_len + extra_null_term);
|
||||
|
||||
uint64_t i = 0;
|
||||
for (uint64_t x = 0; x < mult_amt; x += 1) {
|
||||
for (uint64_t y = 0; y < old_array_len; y += 1) {
|
||||
ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i];
|
||||
copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]);
|
||||
copy_const_val(ira->codegen, elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]);
|
||||
elem_dest_val->parent.id = ConstParentIdArray;
|
||||
elem_dest_val->parent.data.p_array.array_val = out_val;
|
||||
elem_dest_val->parent.data.p_array.elem_index = i;
|
||||
@@ -17542,7 +17542,7 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct
|
||||
|
||||
if (array_type->data.array.sentinel != nullptr) {
|
||||
ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i];
|
||||
copy_const_val(elem_dest_val, array_type->data.array.sentinel);
|
||||
copy_const_val(ira->codegen, elem_dest_val, array_type->data.array.sentinel);
|
||||
elem_dest_val->parent.id = ConstParentIdArray;
|
||||
elem_dest_val->parent.data.p_array.array_val = out_val;
|
||||
elem_dest_val->parent.data.p_array.elem_index = i;
|
||||
@@ -17583,14 +17583,14 @@ static IrInstGen *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira,
|
||||
}
|
||||
|
||||
size_t errors_count = ira->codegen->errors_by_index.length;
|
||||
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *");
|
||||
ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
|
||||
for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) {
|
||||
ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i];
|
||||
assert(errors[error_entry->value] == nullptr);
|
||||
errors[error_entry->value] = error_entry;
|
||||
}
|
||||
ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name);
|
||||
deallocate(errors, errors_count, "ErrorTableEntry *");
|
||||
heap::c_allocator.deallocate(errors, errors_count);
|
||||
|
||||
return ir_const_type(ira, &instruction->base.base, result_type);
|
||||
}
|
||||
@@ -17689,8 +17689,8 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
|
||||
if (var->gen_is_const) {
|
||||
var->const_value = init_val;
|
||||
} else {
|
||||
var->const_value = create_const_vals(1);
|
||||
copy_const_val(var->const_value, init_val);
|
||||
var->const_value = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(ira->codegen, var->const_value, init_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17864,7 +17864,7 @@ static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport
|
||||
// It's not clear how all the different types are supposed to be handled.
|
||||
// Need comprehensive tests for exporting one thing in one file and declaring an extern var
|
||||
// in another file.
|
||||
TldFn *tld_fn = allocate<TldFn>(1);
|
||||
TldFn *tld_fn = heap::c_allocator.create<TldFn>();
|
||||
tld_fn->base.id = TldIdFn;
|
||||
tld_fn->base.source_node = instruction->base.base.source_node;
|
||||
|
||||
@@ -18093,7 +18093,7 @@ static IrInstGen *ir_analyze_instruction_error_union(IrAnalyze *ira, IrInstSrcEr
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueErrUnionType *lazy_err_union_type = allocate<LazyValueErrUnionType>(1, "LazyValueErrUnionType");
|
||||
LazyValueErrUnionType *lazy_err_union_type = heap::c_allocator.create<LazyValueErrUnionType>();
|
||||
lazy_err_union_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_err_union_type->base;
|
||||
lazy_err_union_type->base.id = LazyValueIdErrUnionType;
|
||||
@@ -18114,7 +18114,7 @@ static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType
|
||||
{
|
||||
Error err;
|
||||
|
||||
ZigValue *pointee = create_const_vals(1);
|
||||
ZigValue *pointee = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
pointee->special = ConstValSpecialUndef;
|
||||
pointee->llvm_align = align;
|
||||
|
||||
@@ -18195,8 +18195,8 @@ static bool type_can_bit_cast(ZigType *t) {
|
||||
}
|
||||
}
|
||||
|
||||
static void set_up_result_loc_for_inferred_comptime(IrInstGen *ptr) {
|
||||
ZigValue *undef_child = create_const_vals(1);
|
||||
static void set_up_result_loc_for_inferred_comptime(IrAnalyze *ira, IrInstGen *ptr) {
|
||||
ZigValue *undef_child = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
undef_child->type = ptr->value->type->data.pointer.child_type;
|
||||
undef_child->special = ConstValSpecialUndef;
|
||||
ptr->value->special = ConstValSpecialStatic;
|
||||
@@ -18242,7 +18242,7 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
|
||||
IrInstGenAlloca *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
|
||||
alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
|
||||
PtrLenSingle, 0, 0, 0, false);
|
||||
set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
|
||||
set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base);
|
||||
ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
|
||||
if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
|
||||
fn_entry->alloca_gen_list.append(alloca_gen);
|
||||
@@ -18306,7 +18306,6 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
|
||||
ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope,
|
||||
buf_create_from_str(var->name), var->src_is_const, var->gen_is_const,
|
||||
var->shadowable, var->is_comptime, true);
|
||||
new_var->owner_exec = var->owner_exec;
|
||||
new_var->align_bytes = var->align_bytes;
|
||||
|
||||
var->next_var = new_var;
|
||||
@@ -18645,15 +18644,15 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
|
||||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
field->is_comptime = true;
|
||||
field->init_val = create_const_vals(1);
|
||||
copy_const_val(field->init_val, val);
|
||||
field->init_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(ira->codegen, field->init_val, val);
|
||||
return result_loc;
|
||||
}
|
||||
|
||||
ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
|
||||
if (instr_is_comptime(result_loc)) {
|
||||
casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type);
|
||||
copy_const_val(casted_ptr->value, result_loc->value);
|
||||
copy_const_val(ira->codegen, casted_ptr->value, result_loc->value);
|
||||
casted_ptr->value->type = struct_ptr_type;
|
||||
} else {
|
||||
casted_ptr = result_loc;
|
||||
@@ -18666,8 +18665,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
|
||||
ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
|
||||
suspend_source_instr->source_node);
|
||||
struct_val->special = ConstValSpecialStatic;
|
||||
struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields,
|
||||
old_field_count, new_field_count);
|
||||
struct_val->data.x_struct.fields = realloc_const_vals_ptrs(ira->codegen,
|
||||
struct_val->data.x_struct.fields, old_field_count, new_field_count);
|
||||
|
||||
ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count];
|
||||
field_val->special = ConstValSpecialUndef;
|
||||
@@ -18967,10 +18966,10 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
|
||||
if (!arg_val)
|
||||
return false;
|
||||
} else {
|
||||
arg_val = create_const_runtime(casted_arg->value->type);
|
||||
arg_val = create_const_runtime(ira->codegen, casted_arg->value->type);
|
||||
}
|
||||
if (arg_part_of_generic_id) {
|
||||
copy_const_val(&generic_id->params[generic_id->param_count], arg_val);
|
||||
copy_const_val(ira->codegen, &generic_id->params[generic_id->param_count], arg_val);
|
||||
generic_id->param_count += 1;
|
||||
}
|
||||
|
||||
@@ -19119,7 +19118,7 @@ static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr,
|
||||
if (dest_val == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (dest_val->special != ConstValSpecialRuntime) {
|
||||
copy_const_val(dest_val, value->value);
|
||||
copy_const_val(ira->codegen, dest_val, value->value);
|
||||
|
||||
if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar &&
|
||||
!ira->new_irb.current_basic_block->must_be_comptime_source_instr)
|
||||
@@ -19354,8 +19353,6 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
{
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
destroy(result_ptr, "ZigValue");
|
||||
result_ptr = nullptr;
|
||||
|
||||
if (inferred_err_set_type != nullptr) {
|
||||
inferred_err_set_type->data.error_set.incomplete = false;
|
||||
@@ -19363,7 +19360,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set;
|
||||
if (err != nullptr) {
|
||||
inferred_err_set_type->data.error_set.err_count = 1;
|
||||
inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1);
|
||||
inferred_err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>();
|
||||
inferred_err_set_type->data.error_set.errors[0] = err;
|
||||
}
|
||||
ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type;
|
||||
@@ -19397,12 +19394,12 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
|
||||
size_t new_fn_arg_count = first_arg_1_or_0 + args_len;
|
||||
|
||||
IrInstGen **casted_args = allocate<IrInstGen *>(new_fn_arg_count);
|
||||
IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(new_fn_arg_count);
|
||||
|
||||
// Fork a scope of the function with known values for the parameters.
|
||||
Scope *parent_scope = fn_entry->fndef_scope->base.parent;
|
||||
ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node);
|
||||
impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);
|
||||
impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count);
|
||||
buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
|
||||
impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
|
||||
impl_fn->child_scope = &impl_fn->fndef_scope->base;
|
||||
@@ -19413,10 +19410,10 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
|
||||
// TODO maybe GenericFnTypeId can be replaced with using the child_scope directly
|
||||
// as the key in generic_table
|
||||
GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1);
|
||||
GenericFnTypeId *generic_id = heap::c_allocator.create<GenericFnTypeId>();
|
||||
generic_id->fn_entry = fn_entry;
|
||||
generic_id->param_count = 0;
|
||||
generic_id->params = create_const_vals(new_fn_arg_count);
|
||||
generic_id->params = ira->codegen->pass1_arena->allocate<ZigValue>(new_fn_arg_count);
|
||||
size_t next_proto_i = 0;
|
||||
|
||||
if (first_arg_ptr) {
|
||||
@@ -19476,7 +19473,6 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb,
|
||||
impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
|
||||
const_instruction->base.value = align_result;
|
||||
destroy(result_ptr, "ZigValue");
|
||||
|
||||
uint32_t align_bytes = 0;
|
||||
ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes);
|
||||
@@ -19609,7 +19605,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
}
|
||||
|
||||
|
||||
IrInstGen **casted_args = allocate<IrInstGen *>(call_param_count);
|
||||
IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(call_param_count);
|
||||
size_t next_arg_index = 0;
|
||||
if (first_arg_ptr) {
|
||||
assert(first_arg_ptr->value->type->id == ZigTypeIdPointer);
|
||||
@@ -19741,7 +19737,7 @@ static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_ins
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
new_stack_src = &call_instruction->new_stack->base;
|
||||
}
|
||||
IrInstGen **args_ptr = allocate<IrInstGen *>(call_instruction->arg_count, "IrInstGen *");
|
||||
IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(call_instruction->arg_count);
|
||||
for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
|
||||
args_ptr[i] = call_instruction->args[i]->child;
|
||||
if (type_is_invalid(args_ptr[i]->value->type))
|
||||
@@ -19757,7 +19753,7 @@ static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_ins
|
||||
first_arg_ptr, first_arg_ptr_src, modifier, new_stack, new_stack_src,
|
||||
call_instruction->is_async_call_builtin, args_ptr, call_instruction->arg_count, ret_ptr,
|
||||
call_instruction->result_loc);
|
||||
deallocate(args_ptr, call_instruction->arg_count, "IrInstGen *");
|
||||
heap::c_allocator.deallocate(args_ptr, call_instruction->arg_count);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -19877,7 +19873,7 @@ static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCal
|
||||
|
||||
if (is_tuple(args_type)) {
|
||||
args_len = args_type->data.structure.src_field_count;
|
||||
args_ptr = allocate<IrInstGen *>(args_len, "IrInstGen *");
|
||||
args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len);
|
||||
for (size_t i = 0; i < args_len; i += 1) {
|
||||
TypeStructField *arg_field = args_type->data.structure.fields[i];
|
||||
args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field);
|
||||
@@ -19890,12 +19886,12 @@ static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCal
|
||||
}
|
||||
IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options,
|
||||
instruction->fn_ref, args_ptr, args_len, instruction->result_loc);
|
||||
deallocate(args_ptr, args_len, "IrInstGen *");
|
||||
heap::c_allocator.deallocate(args_ptr, args_len);
|
||||
return result;
|
||||
}
|
||||
|
||||
static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) {
|
||||
IrInstGen **args_ptr = allocate<IrInstGen *>(instruction->args_len, "IrInstGen *");
|
||||
IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len);
|
||||
for (size_t i = 0; i < instruction->args_len; i += 1) {
|
||||
args_ptr[i] = instruction->args_ptr[i]->child;
|
||||
if (type_is_invalid(args_ptr[i]->value->type))
|
||||
@@ -19904,7 +19900,7 @@ static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCall
|
||||
|
||||
IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options,
|
||||
instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc);
|
||||
deallocate(args_ptr, instruction->args_len, "IrInstGen *");
|
||||
heap::c_allocator.deallocate(args_ptr, instruction->args_len);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -19979,7 +19975,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
|
||||
|
||||
if (dst_size <= src_size) {
|
||||
if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) {
|
||||
copy_const_val(out_val, pointee);
|
||||
copy_const_val(codegen, out_val, pointee);
|
||||
return ErrorNone;
|
||||
}
|
||||
Buf buf = BUF_INIT;
|
||||
@@ -20047,7 +20043,7 @@ static IrInstGen *ir_analyze_optional_type(IrAnalyze *ira, IrInstSrcUnOp *instru
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1, "LazyValueOptType");
|
||||
LazyValueOptType *lazy_opt_type = heap::c_allocator.create<LazyValueOptType>();
|
||||
lazy_opt_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_opt_type->base;
|
||||
lazy_opt_type->base.id = LazyValueIdOptType;
|
||||
@@ -20331,7 +20327,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
|
||||
|
||||
if (value->value->special != ConstValSpecialRuntime) {
|
||||
IrInstGen *result = ir_const(ira, &phi_instruction->base.base, nullptr);
|
||||
copy_const_val(result->value, value->value);
|
||||
copy_const_val(ira->codegen, result->value, value->value);
|
||||
return result;
|
||||
} else {
|
||||
return value;
|
||||
@@ -20345,7 +20341,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
|
||||
peer_parent->peers.length >= 2)
|
||||
{
|
||||
if (peer_parent->resolved_type == nullptr) {
|
||||
IrInstGen **instructions = allocate<IrInstGen *>(peer_parent->peers.length);
|
||||
IrInstGen **instructions = heap::c_allocator.allocate<IrInstGen *>(peer_parent->peers.length);
|
||||
for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
|
||||
ResultLocPeer *this_peer = peer_parent->peers.at(i);
|
||||
|
||||
@@ -20718,7 +20714,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
|
||||
if (index == array_len && array_type->data.array.sentinel != nullptr) {
|
||||
ZigType *elem_type = array_type->data.array.child_type;
|
||||
IrInstGen *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base.base, elem_type);
|
||||
copy_const_val(sentinel_elem->value, array_type->data.array.sentinel);
|
||||
copy_const_val(ira->codegen, sentinel_elem->value, array_type->data.array.sentinel);
|
||||
return ir_get_ref(ira, &elem_ptr_instruction->base.base, sentinel_elem, true, false);
|
||||
}
|
||||
if (index >= array_len) {
|
||||
@@ -20782,7 +20778,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
|
||||
{
|
||||
if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) {
|
||||
array_ptr_val->data.x_array.special = ConstArraySpecialNone;
|
||||
array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);
|
||||
array_ptr_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(array_type->data.array.len);
|
||||
array_ptr_val->special = ConstValSpecialStatic;
|
||||
for (size_t i = 0; i < array_type->data.array.len; i += 1) {
|
||||
ZigValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i];
|
||||
@@ -20805,11 +20801,11 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
ZigValue *array_init_val = create_const_vals(1);
|
||||
ZigValue *array_init_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
array_init_val->special = ConstValSpecialStatic;
|
||||
array_init_val->type = actual_array_type;
|
||||
array_init_val->data.x_array.special = ConstArraySpecialNone;
|
||||
array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len);
|
||||
array_init_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(actual_array_type->data.array.len);
|
||||
array_init_val->special = ConstValSpecialStatic;
|
||||
for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) {
|
||||
ZigValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i];
|
||||
@@ -21135,7 +21131,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
|
||||
if (field->is_comptime) {
|
||||
IrInstGen *elem = ir_const(ira, source_instr, field_type);
|
||||
memoize_field_init_val(ira->codegen, struct_type, field);
|
||||
copy_const_val(elem->value, field->init_val);
|
||||
copy_const_val(ira->codegen, elem->value, field->init_val);
|
||||
return ir_get_ref2(ira, source_instr, elem, field_type, true, false);
|
||||
}
|
||||
switch (type_has_one_possible_value(ira->codegen, field_type)) {
|
||||
@@ -21183,7 +21179,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
|
||||
if (type_is_invalid(struct_val->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (initializing && struct_val->special == ConstValSpecialUndef) {
|
||||
struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count);
|
||||
struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
|
||||
struct_val->special = ConstValSpecialStatic;
|
||||
for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
|
||||
ZigValue *field_val = struct_val->data.x_struct.fields[i];
|
||||
@@ -21225,7 +21221,7 @@ static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
|
||||
ZigType *container_ptr_type = container_ptr->value->type;
|
||||
ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr);
|
||||
|
||||
InferredStructField *inferred_struct_field = allocate<InferredStructField>(1, "InferredStructField");
|
||||
InferredStructField *inferred_struct_field = heap::c_allocator.create<InferredStructField>();
|
||||
inferred_struct_field->inferred_struct_type = container_type;
|
||||
inferred_struct_field->field_name = field_name;
|
||||
|
||||
@@ -21245,7 +21241,7 @@ static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
|
||||
} else {
|
||||
result = ir_const(ira, source_instr, field_ptr_type);
|
||||
}
|
||||
copy_const_val(result->value, ptr_val);
|
||||
copy_const_val(ira->codegen, result->value, ptr_val);
|
||||
result->value->type = field_ptr_type;
|
||||
return result;
|
||||
}
|
||||
@@ -21316,7 +21312,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (initializing) {
|
||||
ZigValue *payload_val = create_const_vals(1);
|
||||
ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
payload_val->special = ConstValSpecialUndef;
|
||||
payload_val->type = field_type;
|
||||
payload_val->parent.id = ConstParentIdUnion;
|
||||
@@ -21499,7 +21495,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
}
|
||||
} else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) {
|
||||
if (buf_eql_str(field_name, "len")) {
|
||||
ZigValue *len_val = create_const_vals(1);
|
||||
ZigValue *len_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
if (container_type->id == ZigTypeIdPointer) {
|
||||
init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len);
|
||||
} else {
|
||||
@@ -21545,7 +21541,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_enum(child_type, &field->value), child_type,
|
||||
create_const_enum(ira->codegen, child_type, &field->value), child_type,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
}
|
||||
}
|
||||
@@ -21574,7 +21570,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_enum(enum_type, &field->enum_field->value), enum_type,
|
||||
create_const_enum(ira->codegen, enum_type, &field->enum_field->value), enum_type,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
}
|
||||
}
|
||||
@@ -21592,7 +21588,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
if (existing_entry) {
|
||||
err_entry = existing_entry->value;
|
||||
} else {
|
||||
err_entry = allocate<ErrorTableEntry>(1);
|
||||
err_entry = heap::c_allocator.create<ErrorTableEntry>();
|
||||
err_entry->decl_node = field_ptr_instruction->base.base.source_node;
|
||||
buf_init_from_buf(&err_entry->name, field_name);
|
||||
size_t error_value_count = ira->codegen->errors_by_index.length;
|
||||
@@ -21619,7 +21615,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
}
|
||||
err_set_type = child_type;
|
||||
}
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
ZigValue *const_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = err_set_type;
|
||||
const_val->data.x_err_set = err_entry;
|
||||
@@ -21633,7 +21629,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int,
|
||||
create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int,
|
||||
child_type->data.integral.bit_count, false),
|
||||
ira->codegen->builtin_types.entry_num_lit_int,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
@@ -21655,7 +21651,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int,
|
||||
create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int,
|
||||
child_type->data.floating.bit_count, false),
|
||||
ira->codegen->builtin_types.entry_num_lit_int,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
@@ -21682,7 +21678,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int,
|
||||
create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int,
|
||||
get_ptr_align(ira->codegen, child_type), false),
|
||||
ira->codegen->builtin_types.entry_num_lit_int,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
@@ -21704,7 +21700,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base.base,
|
||||
create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int,
|
||||
create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int,
|
||||
child_type->data.array.len, false),
|
||||
ira->codegen->builtin_types.entry_num_lit_int,
|
||||
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
@@ -21984,7 +21980,7 @@ static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSli
|
||||
IrInstGen *result = ir_const(ira, &slice_type_instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1, "LazyValueSliceType");
|
||||
LazyValueSliceType *lazy_slice_type = heap::c_allocator.create<LazyValueSliceType>();
|
||||
lazy_slice_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_slice_type->base;
|
||||
lazy_slice_type->base.id = LazyValueIdSliceType;
|
||||
@@ -22057,8 +22053,8 @@ static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_i
|
||||
|
||||
// TODO validate the output types and variable types
|
||||
|
||||
IrInstGen **input_list = allocate<IrInstGen *>(asm_expr->input_list.length);
|
||||
IrInstGen **output_types = allocate<IrInstGen *>(asm_expr->output_list.length);
|
||||
IrInstGen **input_list = heap::c_allocator.allocate<IrInstGen *>(asm_expr->input_list.length);
|
||||
IrInstGen **output_types = heap::c_allocator.allocate<IrInstGen *>(asm_expr->output_list.length);
|
||||
|
||||
ZigType *return_type = ira->codegen->builtin_types.entry_void;
|
||||
for (size_t i = 0; i < asm_expr->output_list.length; i += 1) {
|
||||
@@ -22097,7 +22093,7 @@ static IrInstGen *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstSrcArr
|
||||
IrInstGen *result = ir_const(ira, &array_type_instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueArrayType *lazy_array_type = allocate<LazyValueArrayType>(1, "LazyValueArrayType");
|
||||
LazyValueArrayType *lazy_array_type = heap::c_allocator.create<LazyValueArrayType>();
|
||||
lazy_array_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_array_type->base;
|
||||
lazy_array_type->base.id = LazyValueIdArrayType;
|
||||
@@ -22122,7 +22118,7 @@ static IrInstGen *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstSrcSizeOf
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1, "LazyValueSizeOf");
|
||||
LazyValueSizeOf *lazy_size_of = heap::c_allocator.create<LazyValueSizeOf>();
|
||||
lazy_size_of->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_size_of->base;
|
||||
lazy_size_of->base.id = LazyValueIdSizeOf;
|
||||
@@ -22242,7 +22238,7 @@ static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* sou
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
case OnePossibleValueNo:
|
||||
if (!same_comptime_repr) {
|
||||
ZigValue *payload_val = create_const_vals(1);
|
||||
ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
payload_val->type = child_type;
|
||||
payload_val->special = ConstValSpecialUndef;
|
||||
payload_val->parent.id = ConstParentIdOptionalPayload;
|
||||
@@ -22489,7 +22485,7 @@ static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira,
|
||||
}
|
||||
}
|
||||
|
||||
IrInstGenSwitchBrCase *cases = allocate<IrInstGenSwitchBrCase>(case_count);
|
||||
IrInstGenSwitchBrCase *cases = heap::c_allocator.allocate<IrInstGenSwitchBrCase>(case_count);
|
||||
for (size_t i = 0; i < case_count; i += 1) {
|
||||
IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i];
|
||||
IrInstGenSwitchBrCase *new_case = &cases[i];
|
||||
@@ -22574,7 +22570,7 @@ static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira,
|
||||
case ZigTypeIdErrorSet: {
|
||||
if (pointee_val) {
|
||||
IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, nullptr);
|
||||
copy_const_val(result->value, pointee_val);
|
||||
copy_const_val(ira->codegen, result->value, pointee_val);
|
||||
result->value->type = target_type;
|
||||
return result;
|
||||
}
|
||||
@@ -22794,7 +22790,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira,
|
||||
return target_value_ptr;
|
||||
}
|
||||
// Make note of the errors handled by other cases
|
||||
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
|
||||
ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
|
||||
// We may not have any case in the switch if this is a lone else
|
||||
const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0;
|
||||
for (size_t case_i = 0; case_i < switch_cases; case_i += 1) {
|
||||
@@ -22830,7 +22826,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira,
|
||||
buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name));
|
||||
}
|
||||
}
|
||||
free(errors);
|
||||
heap::c_allocator.deallocate(errors, ira->codegen->errors_by_index.length);
|
||||
|
||||
err_set_type->data.error_set.err_count = result_list.length;
|
||||
err_set_type->data.error_set.errors = result_list.items;
|
||||
@@ -22978,7 +22974,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
|
||||
|
||||
IrInstGen *first_non_const_instruction = nullptr;
|
||||
|
||||
AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);
|
||||
AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count);
|
||||
ZigList<IrInstGen *> const_ptrs = {};
|
||||
|
||||
bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope)
|
||||
@@ -23049,7 +23045,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
IrInstGen *runtime_inst = ir_const(ira, source_instr, field->init_val->type);
|
||||
copy_const_val(runtime_inst->value, field->init_val);
|
||||
copy_const_val(ira->codegen, runtime_inst->value, field->init_val);
|
||||
|
||||
IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc,
|
||||
container_type, true);
|
||||
@@ -23313,7 +23309,7 @@ static IrInstGen *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstSrcErrNa
|
||||
err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);
|
||||
}
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
|
||||
copy_const_val(result->value, err->cached_error_name_val);
|
||||
copy_const_val(ira->codegen, result->value, err->cached_error_name_val);
|
||||
result->value->type = str_type;
|
||||
return result;
|
||||
}
|
||||
@@ -23639,11 +23635,11 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
}
|
||||
}
|
||||
|
||||
ZigValue *declaration_array = create_const_vals(1);
|
||||
ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
declaration_array->special = ConstValSpecialStatic;
|
||||
declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr);
|
||||
declaration_array->data.x_array.special = ConstArraySpecialNone;
|
||||
declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count);
|
||||
declaration_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(declaration_count);
|
||||
init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false);
|
||||
|
||||
// Loop through the declarations and generate info.
|
||||
@@ -23665,7 +23661,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
declaration_val->special = ConstValSpecialStatic;
|
||||
declaration_val->type = type_info_declaration_type;
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(3);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3);
|
||||
ZigValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee;
|
||||
init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true);
|
||||
inner_fields[1]->special = ConstValSpecialStatic;
|
||||
@@ -23696,7 +23692,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
// 1: Data.Var: type
|
||||
bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1);
|
||||
|
||||
ZigValue *payload = create_const_vals(1);
|
||||
ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
payload->special = ConstValSpecialStatic;
|
||||
payload->type = ira->codegen->builtin_types.entry_type;
|
||||
payload->data.x_type = var->const_value->type;
|
||||
@@ -23717,13 +23713,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
|
||||
AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto;
|
||||
|
||||
ZigValue *fn_decl_val = create_const_vals(1);
|
||||
ZigValue *fn_decl_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
fn_decl_val->special = ConstValSpecialStatic;
|
||||
fn_decl_val->type = type_info_fn_decl_type;
|
||||
fn_decl_val->parent.id = ConstParentIdUnion;
|
||||
fn_decl_val->parent.data.p_union.union_val = inner_fields[2];
|
||||
|
||||
ZigValue **fn_decl_fields = alloc_const_vals_ptrs(9);
|
||||
ZigValue **fn_decl_fields = alloc_const_vals_ptrs(ira->codegen, 9);
|
||||
fn_decl_val->data.x_struct.fields = fn_decl_fields;
|
||||
|
||||
// fn_type: type
|
||||
@@ -23761,7 +23757,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
0, 0, 0, false);
|
||||
fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
|
||||
if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
|
||||
fn_decl_fields[5]->data.x_optional = create_const_vals(1);
|
||||
fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee;
|
||||
init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0,
|
||||
buf_len(fn_node->lib_name), true);
|
||||
@@ -23776,12 +23772,12 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
// arg_names: [][] const u8
|
||||
ensure_field_index(fn_decl_val->type, "arg_names", 7);
|
||||
size_t fn_arg_count = fn_entry->variable_list.length;
|
||||
ZigValue *fn_arg_name_array = create_const_vals(1);
|
||||
ZigValue *fn_arg_name_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
fn_arg_name_array->special = ConstValSpecialStatic;
|
||||
fn_arg_name_array->type = get_array_type(ira->codegen,
|
||||
get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr);
|
||||
fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
|
||||
fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
|
||||
fn_arg_name_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count);
|
||||
|
||||
init_const_slice(ira->codegen, fn_decl_fields[7], fn_arg_name_array, 0, fn_arg_count, false);
|
||||
|
||||
@@ -23808,7 +23804,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
// This is a type.
|
||||
bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0);
|
||||
|
||||
ZigValue *payload = create_const_vals(1);
|
||||
ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
payload->special = ConstValSpecialStatic;
|
||||
payload->type = ira->codegen->builtin_types.entry_type;
|
||||
payload->data.x_type = type_entry;
|
||||
@@ -23874,11 +23870,11 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_ent
|
||||
ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr);
|
||||
assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown));
|
||||
|
||||
ZigValue *result = create_const_vals(1);
|
||||
ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = type_info_pointer_type;
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(7);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 7);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// size: Size
|
||||
@@ -23933,7 +23929,7 @@ static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEn
|
||||
enum_field_val->special = ConstValSpecialStatic;
|
||||
enum_field_val->type = type_info_enum_field_type;
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(2);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
inner_fields[1]->special = ConstValSpecialStatic;
|
||||
inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
|
||||
|
||||
@@ -23979,11 +23975,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
break;
|
||||
case ZigTypeIdInt:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Int", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(2);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// is_signed: bool
|
||||
@@ -24001,11 +23997,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdFloat:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Float", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(1);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// bits: u8
|
||||
@@ -24025,11 +24021,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdArray:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Array", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(3);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// len: usize
|
||||
@@ -24049,11 +24045,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
break;
|
||||
}
|
||||
case ZigTypeIdVector: {
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Vector", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(2);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// len: usize
|
||||
@@ -24071,11 +24067,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdOptional:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Optional", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(1);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// child: type
|
||||
@@ -24087,11 +24083,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
break;
|
||||
}
|
||||
case ZigTypeIdAnyFrame: {
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(1);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// child: ?type
|
||||
@@ -24104,11 +24100,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdEnum:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Enum", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(5);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// layout: ContainerLayout
|
||||
@@ -24130,11 +24126,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
uint32_t enum_field_count = type_entry->data.enumeration.src_field_count;
|
||||
|
||||
ZigValue *enum_field_array = create_const_vals(1);
|
||||
ZigValue *enum_field_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
enum_field_array->special = ConstValSpecialStatic;
|
||||
enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr);
|
||||
enum_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
|
||||
enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(enum_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false);
|
||||
|
||||
@@ -24164,7 +24160,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdErrorSet:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr);
|
||||
|
||||
@@ -24179,15 +24175,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) {
|
||||
zig_unreachable();
|
||||
}
|
||||
ZigValue *slice_val = create_const_vals(1);
|
||||
ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->data.x_optional = slice_val;
|
||||
|
||||
uint32_t error_count = type_entry->data.error_set.err_count;
|
||||
ZigValue *error_array = create_const_vals(1);
|
||||
ZigValue *error_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
error_array->special = ConstValSpecialStatic;
|
||||
error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr);
|
||||
error_array->data.x_array.special = ConstArraySpecialNone;
|
||||
error_array->data.x_array.data.s_none.elements = create_const_vals(error_count);
|
||||
error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(error_count);
|
||||
|
||||
init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false);
|
||||
for (uint32_t error_index = 0; error_index < error_count; error_index++) {
|
||||
@@ -24197,7 +24193,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
error_val->special = ConstValSpecialStatic;
|
||||
error_val->type = type_info_error_type;
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(2);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
inner_fields[1]->special = ConstValSpecialStatic;
|
||||
inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
|
||||
|
||||
@@ -24219,11 +24215,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdErrorUnion:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(2);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// error_set: type
|
||||
@@ -24242,11 +24238,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdUnion:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Union", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(4);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// layout: ContainerLayout
|
||||
@@ -24263,7 +24259,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
if (union_decl_node->data.container_decl.auto_enum ||
|
||||
union_decl_node->data.container_decl.init_arg_expr != nullptr)
|
||||
{
|
||||
ZigValue *tag_type = create_const_vals(1);
|
||||
ZigValue *tag_type = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
tag_type->special = ConstValSpecialStatic;
|
||||
tag_type->type = ira->codegen->builtin_types.entry_type;
|
||||
tag_type->data.x_type = type_entry->data.unionation.tag_type;
|
||||
@@ -24279,11 +24275,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
zig_unreachable();
|
||||
uint32_t union_field_count = type_entry->data.unionation.src_field_count;
|
||||
|
||||
ZigValue *union_field_array = create_const_vals(1);
|
||||
ZigValue *union_field_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
union_field_array->special = ConstValSpecialStatic;
|
||||
union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr);
|
||||
union_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
|
||||
union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(union_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);
|
||||
|
||||
@@ -24296,14 +24292,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
union_field_val->special = ConstValSpecialStatic;
|
||||
union_field_val->type = type_info_union_field_type;
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(3);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3);
|
||||
inner_fields[1]->special = ConstValSpecialStatic;
|
||||
inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type);
|
||||
|
||||
if (fields[1]->data.x_optional == nullptr) {
|
||||
inner_fields[1]->data.x_optional = nullptr;
|
||||
} else {
|
||||
inner_fields[1]->data.x_optional = create_const_vals(1);
|
||||
inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type);
|
||||
}
|
||||
|
||||
@@ -24338,11 +24334,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
break;
|
||||
}
|
||||
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Struct", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(3);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// layout: ContainerLayout
|
||||
@@ -24359,11 +24355,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
uint32_t struct_field_count = type_entry->data.structure.src_field_count;
|
||||
|
||||
ZigValue *struct_field_array = create_const_vals(1);
|
||||
ZigValue *struct_field_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
struct_field_array->special = ConstValSpecialStatic;
|
||||
struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr);
|
||||
struct_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
|
||||
struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(struct_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false);
|
||||
|
||||
@@ -24374,7 +24370,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
struct_field_val->special = ConstValSpecialStatic;
|
||||
struct_field_val->type = type_info_struct_field_type;
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(4);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4);
|
||||
inner_fields[1]->special = ConstValSpecialStatic;
|
||||
inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
|
||||
|
||||
@@ -24387,7 +24383,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
inner_fields[1]->data.x_optional = nullptr;
|
||||
} else {
|
||||
size_t byte_offset = struct_field->offset;
|
||||
inner_fields[1]->data.x_optional = create_const_vals(1);
|
||||
inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
inner_fields[1]->data.x_optional->special = ConstValSpecialStatic;
|
||||
inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
|
||||
bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset);
|
||||
@@ -24423,11 +24419,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
}
|
||||
case ZigTypeIdFn:
|
||||
{
|
||||
result = create_const_vals(1);
|
||||
result = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
result->special = ConstValSpecialStatic;
|
||||
result->type = ir_type_info_get_type(ira, "Fn", nullptr);
|
||||
|
||||
ZigValue **fields = alloc_const_vals_ptrs(5);
|
||||
ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5);
|
||||
result->data.x_struct.fields = fields;
|
||||
|
||||
// calling_convention: TypeInfo.CallingConvention
|
||||
@@ -24454,7 +24450,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
if (type_entry->data.fn.fn_type_id.return_type == nullptr)
|
||||
fields[3]->data.x_optional = nullptr;
|
||||
else {
|
||||
ZigValue *return_type = create_const_vals(1);
|
||||
ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
return_type->special = ConstValSpecialStatic;
|
||||
return_type->type = ira->codegen->builtin_types.entry_type;
|
||||
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
|
||||
@@ -24468,11 +24464,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count -
|
||||
(is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC);
|
||||
|
||||
ZigValue *fn_arg_array = create_const_vals(1);
|
||||
ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
fn_arg_array->special = ConstValSpecialStatic;
|
||||
fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr);
|
||||
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
|
||||
fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
|
||||
fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count);
|
||||
|
||||
init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false);
|
||||
|
||||
@@ -24486,7 +24482,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
bool arg_is_generic = fn_param_info->type == nullptr;
|
||||
if (arg_is_generic) assert(is_generic);
|
||||
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(3);
|
||||
ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3);
|
||||
inner_fields[0]->special = ConstValSpecialStatic;
|
||||
inner_fields[0]->type = ira->codegen->builtin_types.entry_bool;
|
||||
inner_fields[0]->data.x_bool = arg_is_generic;
|
||||
@@ -24499,7 +24495,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
if (arg_is_generic)
|
||||
inner_fields[2]->data.x_optional = nullptr;
|
||||
else {
|
||||
ZigValue *arg_type = create_const_vals(1);
|
||||
ZigValue *arg_type = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
arg_type->special = ConstValSpecialStatic;
|
||||
arg_type->type = ira->codegen->builtin_types.entry_type;
|
||||
arg_type->data.x_type = fn_param_info->type;
|
||||
@@ -24524,7 +24520,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
break;
|
||||
}
|
||||
case ZigTypeIdFnFrame:
|
||||
zig_panic("TODO @typeInfo for async function frames");
|
||||
ir_add_error(ira, source_instr,
|
||||
buf_sprintf("compiler bug: TODO @typeInfo for async function frames. https://github.com/ziglang/zig/issues/3066"));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
|
||||
assert(result != nullptr);
|
||||
@@ -24823,7 +24821,7 @@ static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcType
|
||||
type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry));
|
||||
}
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
|
||||
copy_const_val(result->value, type_entry->cached_const_name_val);
|
||||
copy_const_val(ira->codegen, result->value, type_entry->cached_const_name_val);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -24855,7 +24853,6 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
|
||||
}
|
||||
if (type_is_invalid(cimport_result->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
destroy(result_ptr, "ZigValue");
|
||||
|
||||
ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope);
|
||||
Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize,
|
||||
@@ -25534,11 +25531,11 @@ static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToByt
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type);
|
||||
result->value->data.x_struct.fields = alloc_const_vals_ptrs(2);
|
||||
result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
|
||||
ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index];
|
||||
ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
|
||||
copy_const_val(ptr_val, target_ptr_val);
|
||||
copy_const_val(ira->codegen, ptr_val, target_ptr_val);
|
||||
ptr_val->type = dest_ptr_type;
|
||||
|
||||
ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index];
|
||||
@@ -25825,7 +25822,7 @@ static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr
|
||||
expand_undef_array(ira->codegen, b_val);
|
||||
|
||||
IrInstGen *result = ir_const(ira, source_instr, result_type);
|
||||
result->value->data.x_array.data.s_none.elements = create_const_vals(len_mask);
|
||||
result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_mask);
|
||||
for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) {
|
||||
ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i];
|
||||
ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i];
|
||||
@@ -25838,7 +25835,7 @@ static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr
|
||||
ZigValue *src_elem_val = (v >= 0) ?
|
||||
&a->value->data.x_array.data.s_none.elements[v] :
|
||||
&b->value->data.x_array.data.s_none.elements[~v];
|
||||
copy_const_val(result_elem_val, src_elem_val);
|
||||
copy_const_val(ira->codegen, result_elem_val, src_elem_val);
|
||||
|
||||
ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr);
|
||||
}
|
||||
@@ -25858,7 +25855,7 @@ static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr
|
||||
|
||||
IrInstGen *expand_mask = ir_const(ira, &mask->base,
|
||||
get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32));
|
||||
expand_mask->value->data.x_array.data.s_none.elements = create_const_vals(len_max);
|
||||
expand_mask->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_max);
|
||||
uint32_t i = 0;
|
||||
for (; i < len_min; i += 1)
|
||||
bigint_init_unsigned(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, i);
|
||||
@@ -25928,9 +25925,9 @@ static IrInstGen *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstSrcSplat *i
|
||||
return ir_const_undef(ira, &instruction->base.base, return_type);
|
||||
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);
|
||||
result->value->data.x_array.data.s_none.elements = create_const_vals(len_int);
|
||||
result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_int);
|
||||
for (uint32_t i = 0; i < len_int; i += 1) {
|
||||
copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val);
|
||||
copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], scalar_val);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -26068,7 +26065,7 @@ static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset
|
||||
}
|
||||
|
||||
for (size_t i = start; i < end; i += 1) {
|
||||
copy_const_val(&dest_elements[i], byte_val);
|
||||
copy_const_val(ira->codegen, &dest_elements[i], byte_val);
|
||||
}
|
||||
|
||||
return ir_const_void(ira, &instruction->base.base);
|
||||
@@ -26244,7 +26241,7 @@ static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy
|
||||
// TODO check for noalias violations - this should be generalized to work for any function
|
||||
|
||||
for (size_t i = 0; i < count; i += 1) {
|
||||
copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i]);
|
||||
copy_const_val(ira->codegen, &dest_elements[dest_start + i], &src_elements[src_start + i]);
|
||||
}
|
||||
|
||||
return ir_const_void(ira, &instruction->base.base);
|
||||
@@ -26528,7 +26525,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
|
||||
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);
|
||||
ZigValue *out_val = result->value;
|
||||
out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
|
||||
out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
|
||||
|
||||
ZigValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index];
|
||||
|
||||
@@ -26823,7 +26820,7 @@ static IrInstGen *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstSrcAlign
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1, "LazyValueAlignOf");
|
||||
LazyValueAlignOf *lazy_align_of = heap::c_allocator.create<LazyValueAlignOf>();
|
||||
lazy_align_of->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_align_of->base;
|
||||
lazy_align_of->base.id = LazyValueIdAlignOf;
|
||||
@@ -27149,7 +27146,7 @@ static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_inst
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (initializing && err_union_val->special == ConstValSpecialUndef) {
|
||||
ZigValue *vals = create_const_vals(2);
|
||||
ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2);
|
||||
ZigValue *err_set_val = &vals[0];
|
||||
ZigValue *payload_val = &vals[1];
|
||||
|
||||
@@ -27230,7 +27227,7 @@ static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source
|
||||
if (err_union_val == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (initializing && err_union_val->special == ConstValSpecialUndef) {
|
||||
ZigValue *vals = create_const_vals(2);
|
||||
ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2);
|
||||
ZigValue *err_set_val = &vals[0];
|
||||
ZigValue *payload_val = &vals[1];
|
||||
|
||||
@@ -27292,7 +27289,7 @@ static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnPro
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1, "LazyValueFnType");
|
||||
LazyValueFnType *lazy_fn_type = heap::c_allocator.create<LazyValueFnType>();
|
||||
lazy_fn_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_fn_type->base;
|
||||
lazy_fn_type->base.id = LazyValueIdFnType;
|
||||
@@ -27320,7 +27317,7 @@ static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnPro
|
||||
|
||||
size_t param_count = proto_node->data.fn_proto.params.length;
|
||||
lazy_fn_type->proto_node = proto_node;
|
||||
lazy_fn_type->param_types = allocate<IrInstGen *>(param_count);
|
||||
lazy_fn_type->param_types = heap::c_allocator.allocate<IrInstGen *>(param_count);
|
||||
|
||||
for (size_t param_index = 0; param_index < param_count; param_index += 1) {
|
||||
AstNode *param_node = proto_node->data.fn_proto.params.at(param_index);
|
||||
@@ -27475,7 +27472,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
|
||||
}
|
||||
|
||||
size_t field_prev_uses_count = ira->codegen->errors_by_index.length;
|
||||
AstNode **field_prev_uses = allocate<AstNode *>(field_prev_uses_count, "AstNode *");
|
||||
AstNode **field_prev_uses = heap::c_allocator.allocate<AstNode *>(field_prev_uses_count);
|
||||
|
||||
for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
|
||||
IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i];
|
||||
@@ -27532,7 +27529,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
|
||||
}
|
||||
}
|
||||
|
||||
deallocate(field_prev_uses, field_prev_uses_count, "AstNode *");
|
||||
heap::c_allocator.deallocate(field_prev_uses, field_prev_uses_count);
|
||||
} else if (switch_type->id == ZigTypeIdInt) {
|
||||
RangeSet rs = {0};
|
||||
for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
|
||||
@@ -27725,7 +27722,7 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig
|
||||
}
|
||||
|
||||
IrInstGen *result = ir_const(ira, &target->base, result_type);
|
||||
copy_const_val(result->value, val);
|
||||
copy_const_val(ira->codegen, result->value, val);
|
||||
result->value->type = result_type;
|
||||
return result;
|
||||
}
|
||||
@@ -27821,7 +27818,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
||||
InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ?
|
||||
val->type->data.pointer.inferred_struct_field : nullptr;
|
||||
if (isf == nullptr) {
|
||||
copy_const_val(result->value, val);
|
||||
copy_const_val(ira->codegen, result->value, val);
|
||||
} else {
|
||||
// The destination value should have x_ptr struct pointing to underlying struct value
|
||||
result->value->data.x_ptr.mut = val->data.x_ptr.mut;
|
||||
@@ -27978,7 +27975,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
|
||||
while (gen_i < gen_field_count) {
|
||||
size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i];
|
||||
if (big_int_byte_count > child_buf_len) {
|
||||
child_buf = allocate_nonzero<uint8_t>(big_int_byte_count);
|
||||
child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count);
|
||||
child_buf_len = big_int_byte_count;
|
||||
}
|
||||
BigInt big_int;
|
||||
@@ -28041,7 +28038,7 @@ static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNod
|
||||
|
||||
switch (val->data.x_array.special) {
|
||||
case ConstArraySpecialNone:
|
||||
val->data.x_array.data.s_none.elements = create_const_vals(len);
|
||||
val->data.x_array.data.s_none.elements = codegen->pass1_arena->allocate<ZigValue>(len);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ZigValue *elem = &val->data.x_array.data.s_none.elements[i];
|
||||
elem->special = ConstValSpecialStatic;
|
||||
@@ -28127,7 +28124,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
|
||||
}
|
||||
case ContainerLayoutExtern: {
|
||||
size_t src_field_count = val->type->data.structure.src_field_count;
|
||||
val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
|
||||
val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count);
|
||||
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
|
||||
ZigValue *field_val = val->data.x_struct.fields[field_i];
|
||||
field_val->special = ConstValSpecialStatic;
|
||||
@@ -28144,7 +28141,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
|
||||
}
|
||||
case ContainerLayoutPacked: {
|
||||
size_t src_field_count = val->type->data.structure.src_field_count;
|
||||
val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
|
||||
val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count);
|
||||
size_t gen_field_count = val->type->data.structure.gen_field_count;
|
||||
size_t gen_i = 0;
|
||||
size_t src_i = 0;
|
||||
@@ -28156,7 +28153,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
|
||||
while (gen_i < gen_field_count) {
|
||||
size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i];
|
||||
if (big_int_byte_count > child_buf_len) {
|
||||
child_buf = allocate_nonzero<uint8_t>(big_int_byte_count);
|
||||
child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count);
|
||||
child_buf_len = big_int_byte_count;
|
||||
}
|
||||
BigInt big_int;
|
||||
@@ -28266,7 +28263,7 @@ static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
IrInstGen *result = ir_const(ira, source_instr, dest_type);
|
||||
uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes);
|
||||
uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(src_size_bytes);
|
||||
buf_write_value_bytes(ira->codegen, buf, val);
|
||||
if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
@@ -28408,7 +28405,7 @@ static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrTy
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
|
||||
result->value->special = ConstValSpecialLazy;
|
||||
|
||||
LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1, "LazyValuePtrType");
|
||||
LazyValuePtrType *lazy_ptr_type = heap::c_allocator.create<LazyValuePtrType>();
|
||||
lazy_ptr_type->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_ptr_type->base;
|
||||
lazy_ptr_type->base.id = LazyValueIdPtrType;
|
||||
@@ -29107,11 +29104,11 @@ static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *i
|
||||
return ir_const_undef(ira, &instruction->base.base, op_type);
|
||||
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, op_type);
|
||||
size_t buf_size = int_type->data.integral.bit_count / 8;
|
||||
uint8_t *buf = allocate_nonzero<uint8_t>(buf_size);
|
||||
const size_t buf_size = int_type->data.integral.bit_count / 8;
|
||||
uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size);
|
||||
if (is_vector) {
|
||||
expand_undef_array(ira->codegen, val);
|
||||
result->value->data.x_array.data.s_none.elements = create_const_vals(op_type->data.vector.len);
|
||||
result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(op_type->data.vector.len);
|
||||
for (unsigned i = 0; i < op_type->data.vector.len; i += 1) {
|
||||
ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i];
|
||||
if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.base.source_node,
|
||||
@@ -29135,7 +29132,7 @@ static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *i
|
||||
bigint_read_twos_complement(&result->value->data.x_bigint, buf, int_type->data.integral.bit_count, false,
|
||||
int_type->data.integral.is_signed);
|
||||
}
|
||||
free(buf);
|
||||
heap::c_allocator.deallocate(buf, buf_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -29167,8 +29164,8 @@ static IrInstGen *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstSrcBi
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, int_type);
|
||||
size_t num_bits = int_type->data.integral.bit_count;
|
||||
size_t buf_size = (num_bits + 7) / 8;
|
||||
uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size);
|
||||
uint8_t *result_buf = allocate_nonzero<uint8_t>(buf_size);
|
||||
uint8_t *comptime_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size);
|
||||
uint8_t *result_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size);
|
||||
memset(comptime_buf,0,buf_size);
|
||||
memset(result_buf,0,buf_size);
|
||||
|
||||
@@ -29854,7 +29851,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
|
||||
assert(old_exec->first_err_trace_msg == nullptr);
|
||||
assert(expected_type == nullptr || !type_is_invalid(expected_type));
|
||||
|
||||
IrAnalyze *ira = allocate<IrAnalyze>(1, "IrAnalyze");
|
||||
IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>();
|
||||
ira->ref_count = 1;
|
||||
old_exec->analysis = ira;
|
||||
ira->codegen = codegen;
|
||||
|
||||
@@ -37,6 +37,4 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va
|
||||
void dbg_ir_break(const char *src_file, uint32_t line);
|
||||
void dbg_ir_clear(void);
|
||||
|
||||
void destroy_instruction_gen(IrInstGen *inst);
|
||||
|
||||
#endif
|
||||
|
||||
+19
-26
@@ -650,7 +650,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
|
||||
};
|
||||
ZigList<CFile *> c_source_files = {0};
|
||||
for (size_t i = 0; i < array_length(unwind_src); i += 1) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libunwind(parent, unwind_src[i].path);
|
||||
switch (unwind_src[i].kind) {
|
||||
case SrcC:
|
||||
@@ -1111,7 +1111,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
|
||||
Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
|
||||
buf_ptr(parent->zig_lib_dir), buf_ptr(src_file));
|
||||
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = buf_ptr(full_path);
|
||||
|
||||
musl_add_cc_args(parent, c_file, src_kind == MuslSrcO3);
|
||||
@@ -1127,7 +1127,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
|
||||
}
|
||||
|
||||
static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
|
||||
buf_ptr(parent->zig_lib_dir), src_path));
|
||||
c_file->args.append("-DHAVE_CONFIG_H");
|
||||
@@ -1151,7 +1151,7 @@ static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *s
|
||||
}
|
||||
|
||||
static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
|
||||
buf_ptr(parent->zig_lib_dir), src_path));
|
||||
c_file->args.append("-DHAVE_CONFIG_H");
|
||||
@@ -1178,7 +1178,7 @@ static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char *
|
||||
static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2ProgressNode *progress_node) {
|
||||
if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
|
||||
if (strcmp(file, "crt2.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = buf_ptr(buf_sprintf(
|
||||
"%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtexe.c", buf_ptr(parent->zig_lib_dir)));
|
||||
mingw_add_cc_args(parent, c_file);
|
||||
@@ -1190,7 +1190,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
//c_file->args.append("-DWPRFLAG=1");
|
||||
return build_libc_object(parent, "crt2", c_file, progress_node);
|
||||
} else if (strcmp(file, "dllcrt2.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = buf_ptr(buf_sprintf(
|
||||
"%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtdll.c", buf_ptr(parent->zig_lib_dir)));
|
||||
mingw_add_cc_args(parent, c_file);
|
||||
@@ -1231,7 +1231,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
"mingw" OS_SEP "crt" OS_SEP "cxa_atexit.c",
|
||||
};
|
||||
for (size_t i = 0; i < array_length(deps); i += 1) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, deps[i]);
|
||||
c_file->args.append("-DHAVE_CONFIG_H");
|
||||
c_file->args.append("-D_SYSCRT=1");
|
||||
@@ -1301,7 +1301,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
}
|
||||
} else if (parent->libc == nullptr && target_is_glibc(parent->zig_target)) {
|
||||
if (strcmp(file, "crti.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = glibc_start_asm_path(parent, "crti.S");
|
||||
glibc_add_include_dirs(parent, c_file);
|
||||
c_file->args.append("-D_LIBC_REENTRANT");
|
||||
@@ -1317,7 +1317,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
c_file->args.append("-Wa,--noexecstack");
|
||||
return build_libc_object(parent, "crti", c_file, progress_node);
|
||||
} else if (strcmp(file, "crtn.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = glibc_start_asm_path(parent, "crtn.S");
|
||||
glibc_add_include_dirs(parent, c_file);
|
||||
c_file->args.append("-D_LIBC_REENTRANT");
|
||||
@@ -1328,7 +1328,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
c_file->args.append("-Wa,--noexecstack");
|
||||
return build_libc_object(parent, "crtn", c_file, progress_node);
|
||||
} else if (strcmp(file, "start.os") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = glibc_start_asm_path(parent, "start.S");
|
||||
glibc_add_include_dirs(parent, c_file);
|
||||
c_file->args.append("-D_LIBC_REENTRANT");
|
||||
@@ -1346,7 +1346,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
c_file->args.append("-Wa,--noexecstack");
|
||||
return build_libc_object(parent, "start", c_file, progress_node);
|
||||
} else if (strcmp(file, "abi-note.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S");
|
||||
c_file->args.append("-I");
|
||||
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu"));
|
||||
@@ -1369,7 +1369,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
} else if (strcmp(file, "libc_nonshared.a") == 0) {
|
||||
CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
|
||||
{
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c");
|
||||
c_file->args.append("-std=gnu11");
|
||||
c_file->args.append("-fgnu89-inline");
|
||||
@@ -1419,7 +1419,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
{"stack_chk_fail_local", "glibc" OS_SEP "debug" OS_SEP "stack_chk_fail_local.c"},
|
||||
};
|
||||
for (size_t i = 0; i < array_length(deps); i += 1) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, deps[i].path);
|
||||
c_file->args.append("-std=gnu11");
|
||||
c_file->args.append("-fgnu89-inline");
|
||||
@@ -1451,26 +1451,26 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
}
|
||||
} else if (parent->libc == nullptr && target_is_musl(parent->zig_target)) {
|
||||
if (strcmp(file, "crti.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = musl_start_asm_path(parent, "crti.s");
|
||||
musl_add_cc_args(parent, c_file, false);
|
||||
c_file->args.append("-Qunused-arguments");
|
||||
return build_libc_object(parent, "crti", c_file, progress_node);
|
||||
} else if (strcmp(file, "crtn.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = musl_start_asm_path(parent, "crtn.s");
|
||||
c_file->args.append("-Qunused-arguments");
|
||||
musl_add_cc_args(parent, c_file, false);
|
||||
return build_libc_object(parent, "crtn", c_file, progress_node);
|
||||
} else if (strcmp(file, "crt1.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
|
||||
musl_add_cc_args(parent, c_file, false);
|
||||
c_file->args.append("-fno-stack-protector");
|
||||
c_file->args.append("-DCRT");
|
||||
return build_libc_object(parent, "crt1", c_file, progress_node);
|
||||
} else if (strcmp(file, "Scrt1.o") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
|
||||
musl_add_cc_args(parent, c_file, false);
|
||||
c_file->args.append("-fPIC");
|
||||
@@ -1987,7 +1987,7 @@ static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_fi
|
||||
Buf *def_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "def-include",
|
||||
buf_ptr(parent->zig_lib_dir));
|
||||
|
||||
CacheHash *cache_hash = allocate<CacheHash>(1);
|
||||
CacheHash *cache_hash = heap::c_allocator.create<CacheHash>();
|
||||
cache_init(cache_hash, manifest_dir);
|
||||
|
||||
cache_buf(cache_hash, compiler_id);
|
||||
@@ -2372,7 +2372,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
|
||||
lj->args.append(get_def_lib(g, name, &lib_path));
|
||||
|
||||
free(name);
|
||||
mem::os::free(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2647,13 +2647,6 @@ void codegen_link(CodeGen *g) {
|
||||
lj.rpath_table.init(4);
|
||||
lj.codegen = g;
|
||||
|
||||
if (g->verbose_llvm_ir) {
|
||||
fprintf(stderr, "\nOptimization:\n");
|
||||
fprintf(stderr, "---------------\n");
|
||||
fflush(stderr);
|
||||
LLVMDumpModule(g->module);
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeObj) {
|
||||
lj.args.append("-r");
|
||||
}
|
||||
|
||||
+2
-4
@@ -13,7 +13,7 @@
|
||||
template<typename T>
|
||||
struct ZigList {
|
||||
void deinit() {
|
||||
deallocate(items, capacity);
|
||||
heap::c_allocator.deallocate(items, capacity);
|
||||
}
|
||||
void append(const T& item) {
|
||||
ensure_capacity(length + 1);
|
||||
@@ -70,7 +70,7 @@ struct ZigList {
|
||||
better_capacity = better_capacity * 5 / 2 + 8;
|
||||
} while (better_capacity < new_capacity);
|
||||
|
||||
items = reallocate_nonzero(items, capacity, better_capacity);
|
||||
items = heap::c_allocator.reallocate_nonzero(items, capacity, better_capacity);
|
||||
capacity = better_capacity;
|
||||
}
|
||||
|
||||
@@ -91,5 +91,3 @@ struct ZigList {
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+27
-21
@@ -11,12 +11,14 @@
|
||||
#include "compiler.hpp"
|
||||
#include "config.h"
|
||||
#include "error.hpp"
|
||||
#include "heap.hpp"
|
||||
#include "os.hpp"
|
||||
#include "target.hpp"
|
||||
#include "libc_installation.hpp"
|
||||
#include "userland.h"
|
||||
#include "glibc.hpp"
|
||||
#include "dump_analysis.hpp"
|
||||
#include "mem_profile.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -243,21 +245,10 @@ int main_exit(Stage2ProgressNode *root_progress_node, int exit_code) {
|
||||
if (root_progress_node != nullptr) {
|
||||
stage2_progress_end(root_progress_node);
|
||||
}
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
if (mem_report) {
|
||||
memprof_dump_stats(stderr);
|
||||
}
|
||||
#endif
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
stage2_attach_segfault_handler();
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_init();
|
||||
#endif
|
||||
|
||||
static int main0(int argc, char **argv) {
|
||||
char *arg0 = argv[0];
|
||||
Error err;
|
||||
|
||||
@@ -279,9 +270,6 @@ int main(int argc, char **argv) {
|
||||
return ZigClang_main(argc, argv);
|
||||
}
|
||||
|
||||
// Must be before all os.hpp function calls.
|
||||
os_init();
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "id") == 0) {
|
||||
Buf *compiler_id;
|
||||
if ((err = get_compiler_id(&compiler_id))) {
|
||||
@@ -440,7 +428,7 @@ int main(int argc, char **argv) {
|
||||
bool enable_doc_generation = false;
|
||||
bool disable_bin_generation = false;
|
||||
const char *cache_dir = nullptr;
|
||||
CliPkg *cur_pkg = allocate<CliPkg>(1);
|
||||
CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();
|
||||
BuildMode build_mode = BuildModeDebug;
|
||||
ZigList<const char *> test_exec_args = {0};
|
||||
int runtime_args_start = -1;
|
||||
@@ -636,6 +624,7 @@ int main(int argc, char **argv) {
|
||||
} else if (strcmp(arg, "-fmem-report") == 0) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
mem_report = true;
|
||||
mem::report_print = true;
|
||||
#else
|
||||
fprintf(stderr, "-fmem-report requires configuring with -DZIG_ENABLE_MEM_PROFILE=ON\n");
|
||||
return print_error_usage(arg0);
|
||||
@@ -696,7 +685,7 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr, "Expected 2 arguments after --pkg-begin\n");
|
||||
return print_error_usage(arg0);
|
||||
}
|
||||
CliPkg *new_cur_pkg = allocate<CliPkg>(1);
|
||||
CliPkg *new_cur_pkg = heap::c_allocator.create<CliPkg>();
|
||||
i += 1;
|
||||
new_cur_pkg->name = argv[i];
|
||||
i += 1;
|
||||
@@ -811,7 +800,7 @@ int main(int argc, char **argv) {
|
||||
} else if (strcmp(arg, "--object") == 0) {
|
||||
objects.append(argv[i]);
|
||||
} else if (strcmp(arg, "--c-source") == 0) {
|
||||
CFile *c_file = allocate<CFile>(1);
|
||||
CFile *c_file = heap::c_allocator.create<CFile>();
|
||||
for (;;) {
|
||||
if (argv[i][0] == '-') {
|
||||
c_file->args.append(argv[i]);
|
||||
@@ -991,7 +980,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
if (target_is_glibc(&target)) {
|
||||
target.glibc_version = allocate<ZigGLibCVersion>(1);
|
||||
target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
|
||||
|
||||
if (target_glibc != nullptr) {
|
||||
if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {
|
||||
@@ -1139,7 +1128,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
ZigLibCInstallation *libc = nullptr;
|
||||
if (libc_txt != nullptr) {
|
||||
libc = allocate<ZigLibCInstallation>(1);
|
||||
libc = heap::c_allocator.create<ZigLibCInstallation>();
|
||||
if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {
|
||||
fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
|
||||
return main_exit(root_progress_node, EXIT_FAILURE);
|
||||
@@ -1270,7 +1259,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (cmd == CmdRun) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_dump_stats(stderr);
|
||||
if (mem::report_print)
|
||||
mem::print_report();
|
||||
#endif
|
||||
|
||||
const char *exec_path = buf_ptr(&g->output_file_path);
|
||||
@@ -1385,4 +1375,20 @@ int main(int argc, char **argv) {
|
||||
case CmdNone:
|
||||
return print_full_usage(arg0, stderr, EXIT_FAILURE);
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
stage2_attach_segfault_handler();
|
||||
os_init();
|
||||
mem::init();
|
||||
|
||||
auto result = main0(argc, argv);
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
if (mem::report_print)
|
||||
mem::intern_counters.print_report();
|
||||
#endif
|
||||
mem::deinit();
|
||||
return result;
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "mem.hpp"
|
||||
#include "mem_profile.hpp"
|
||||
#include "heap.hpp"
|
||||
|
||||
namespace mem {
|
||||
|
||||
void init() {
|
||||
heap::bootstrap_allocator_state.init("heap::bootstrap_allocator");
|
||||
heap::c_allocator_state.init("heap::c_allocator");
|
||||
}
|
||||
|
||||
void deinit() {
|
||||
heap::c_allocator_state.deinit();
|
||||
heap::bootstrap_allocator_state.deinit();
|
||||
}
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void print_report(FILE *file) {
|
||||
heap::c_allocator_state.print_report(file);
|
||||
intern_counters.print_report(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
bool report_print = false;
|
||||
FILE *report_file{nullptr};
|
||||
#endif
|
||||
|
||||
} // namespace mem
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEM_HPP
|
||||
#define ZIG_MEM_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util_base.hpp"
|
||||
#include "mem_type_info.hpp"
|
||||
|
||||
//
|
||||
// -- Memory Allocation General Notes --
|
||||
//
|
||||
// `heap::c_allocator` is the preferred general allocator.
|
||||
//
|
||||
// `heap::bootstrap_allocator` is an implementation detail for use
|
||||
// by allocators themselves when incidental heap may be required for
|
||||
// profiling and statistics. It breaks the infinite recursion cycle.
|
||||
//
|
||||
// `mem::os` contains a raw wrapper for system malloc API used in
|
||||
// preference to calling ::{malloc, free, calloc, realloc} directly.
|
||||
// This isolates usage and helps with audits:
|
||||
//
|
||||
// mem::os::malloc
|
||||
// mem::os::free
|
||||
// mem::os::calloc
|
||||
// mem::os::realloc
|
||||
//
|
||||
namespace mem {
|
||||
|
||||
// initialize mem module before any use
|
||||
void init();
|
||||
|
||||
// deinitialize mem module to free memory and print report
|
||||
void deinit();
|
||||
|
||||
// isolate system/libc allocators
|
||||
namespace os {
|
||||
|
||||
ATTRIBUTE_RETURNS_NOALIAS
|
||||
inline void *malloc(size_t size) {
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (size == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
auto ptr = ::malloc(size);
|
||||
if (ptr == nullptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void free(void *ptr) {
|
||||
::free(ptr);
|
||||
}
|
||||
|
||||
ATTRIBUTE_RETURNS_NOALIAS
|
||||
inline void *calloc(size_t count, size_t size) {
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (count == 0 || size == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
auto ptr = ::calloc(count, size);
|
||||
if (ptr == nullptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void *realloc(void *old_ptr, size_t size) {
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (old_ptr == nullptr && size == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
auto ptr = ::realloc(old_ptr, size);
|
||||
if (ptr == nullptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
} // namespace os
|
||||
|
||||
struct Allocator {
|
||||
virtual void destruct(Allocator *allocator) = 0;
|
||||
|
||||
template <typename T> ATTRIBUTE_RETURNS_NOALIAS
|
||||
T *allocate(size_t count) {
|
||||
return reinterpret_cast<T *>(this->internal_allocate(TypeInfo::make<T>(), count));
|
||||
}
|
||||
|
||||
template <typename T> ATTRIBUTE_RETURNS_NOALIAS
|
||||
T *allocate_nonzero(size_t count) {
|
||||
return reinterpret_cast<T *>(this->internal_allocate_nonzero(TypeInfo::make<T>(), count));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *reallocate(T *old_ptr, size_t old_count, size_t new_count) {
|
||||
return reinterpret_cast<T *>(this->internal_reallocate(TypeInfo::make<T>(), old_ptr, old_count, new_count));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *reallocate_nonzero(T *old_ptr, size_t old_count, size_t new_count) {
|
||||
return reinterpret_cast<T *>(this->internal_reallocate_nonzero(TypeInfo::make<T>(), old_ptr, old_count, new_count));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void deallocate(T *ptr, size_t count) {
|
||||
this->internal_deallocate(TypeInfo::make<T>(), ptr, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *create() {
|
||||
return reinterpret_cast<T *>(this->internal_allocate(TypeInfo::make<T>(), 1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void destroy(T *ptr) {
|
||||
this->internal_deallocate(TypeInfo::make<T>(), ptr, 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
ATTRIBUTE_RETURNS_NOALIAS virtual void *internal_allocate(const TypeInfo &info, size_t count) = 0;
|
||||
ATTRIBUTE_RETURNS_NOALIAS virtual void *internal_allocate_nonzero(const TypeInfo &info, size_t count) = 0;
|
||||
virtual void *internal_reallocate(const TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) = 0;
|
||||
virtual void *internal_reallocate_nonzero(const TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) = 0;
|
||||
virtual void internal_deallocate(const TypeInfo &info, void *ptr, size_t count) = 0;
|
||||
};
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
void print_report(FILE *file = nullptr);
|
||||
|
||||
// global memory report flag
|
||||
extern bool report_print;
|
||||
// global memory report default destination
|
||||
extern FILE *report_file;
|
||||
#endif
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEM_HASH_MAP_HPP
|
||||
#define ZIG_MEM_HASH_MAP_HPP
|
||||
|
||||
#include "mem.hpp"
|
||||
|
||||
namespace mem {
|
||||
|
||||
template<typename K, typename V, uint32_t (*HashFunction)(K key), bool (*EqualFn)(K a, K b)>
|
||||
class HashMap {
|
||||
public:
|
||||
void init(Allocator& allocator, int capacity) {
|
||||
init_capacity(allocator, capacity);
|
||||
}
|
||||
void deinit(Allocator& allocator) {
|
||||
allocator.deallocate(_entries, _capacity);
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
K key;
|
||||
V value;
|
||||
bool used;
|
||||
int distance_from_start_index;
|
||||
};
|
||||
|
||||
void clear() {
|
||||
for (int i = 0; i < _capacity; i += 1) {
|
||||
_entries[i].used = false;
|
||||
}
|
||||
_size = 0;
|
||||
_max_distance_from_start_index = 0;
|
||||
_modification_count += 1;
|
||||
}
|
||||
|
||||
int size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void put(Allocator& allocator, const K &key, const V &value) {
|
||||
_modification_count += 1;
|
||||
internal_put(key, value);
|
||||
|
||||
// if we get too full (60%), double the capacity
|
||||
if (_size * 5 >= _capacity * 3) {
|
||||
Entry *old_entries = _entries;
|
||||
int old_capacity = _capacity;
|
||||
init_capacity(allocator, _capacity * 2);
|
||||
// dump all of the old elements into the new table
|
||||
for (int i = 0; i < old_capacity; i += 1) {
|
||||
Entry *old_entry = &old_entries[i];
|
||||
if (old_entry->used)
|
||||
internal_put(old_entry->key, old_entry->value);
|
||||
}
|
||||
allocator.deallocate(old_entries, old_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
Entry *put_unique(Allocator& allocator, const K &key, const V &value) {
|
||||
// TODO make this more efficient
|
||||
Entry *entry = internal_get(key);
|
||||
if (entry)
|
||||
return entry;
|
||||
put(allocator, key, value);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const V &get(const K &key) const {
|
||||
Entry *entry = internal_get(key);
|
||||
if (!entry)
|
||||
zig_panic("key not found");
|
||||
return entry->value;
|
||||
}
|
||||
|
||||
Entry *maybe_get(const K &key) const {
|
||||
return internal_get(key);
|
||||
}
|
||||
|
||||
void maybe_remove(const K &key) {
|
||||
if (maybe_get(key)) {
|
||||
remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
void remove(const K &key) {
|
||||
_modification_count += 1;
|
||||
int start_index = key_to_index(key);
|
||||
for (int roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {
|
||||
int index = (start_index + roll_over) % _capacity;
|
||||
Entry *entry = &_entries[index];
|
||||
|
||||
if (!entry->used)
|
||||
zig_panic("key not found");
|
||||
|
||||
if (!EqualFn(entry->key, key))
|
||||
continue;
|
||||
|
||||
for (; roll_over < _capacity; roll_over += 1) {
|
||||
int next_index = (start_index + roll_over + 1) % _capacity;
|
||||
Entry *next_entry = &_entries[next_index];
|
||||
if (!next_entry->used || next_entry->distance_from_start_index == 0) {
|
||||
entry->used = false;
|
||||
_size -= 1;
|
||||
return;
|
||||
}
|
||||
*entry = *next_entry;
|
||||
entry->distance_from_start_index -= 1;
|
||||
entry = next_entry;
|
||||
}
|
||||
zig_panic("shifting everything in the table");
|
||||
}
|
||||
zig_panic("key not found");
|
||||
}
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
Entry *next() {
|
||||
if (_inital_modification_count != _table->_modification_count)
|
||||
zig_panic("concurrent modification");
|
||||
if (_count >= _table->size())
|
||||
return NULL;
|
||||
for (; _index < _table->_capacity; _index += 1) {
|
||||
Entry *entry = &_table->_entries[_index];
|
||||
if (entry->used) {
|
||||
_index += 1;
|
||||
_count += 1;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
zig_panic("no next item");
|
||||
}
|
||||
|
||||
private:
|
||||
const HashMap * _table;
|
||||
// how many items have we returned
|
||||
int _count = 0;
|
||||
// iterator through the entry array
|
||||
int _index = 0;
|
||||
// used to detect concurrent modification
|
||||
uint32_t _inital_modification_count;
|
||||
Iterator(const HashMap * table) :
|
||||
_table(table), _inital_modification_count(table->_modification_count) {
|
||||
}
|
||||
friend HashMap;
|
||||
};
|
||||
|
||||
// you must not modify the underlying HashMap while this iterator is still in use
|
||||
Iterator entry_iterator() const {
|
||||
return Iterator(this);
|
||||
}
|
||||
|
||||
private:
|
||||
Entry *_entries;
|
||||
int _capacity;
|
||||
int _size;
|
||||
int _max_distance_from_start_index;
|
||||
// this is used to detect bugs where a hashtable is edited while an iterator is running.
|
||||
uint32_t _modification_count;
|
||||
|
||||
void init_capacity(Allocator& allocator, int capacity) {
|
||||
_capacity = capacity;
|
||||
_entries = allocator.allocate<Entry>(_capacity);
|
||||
_size = 0;
|
||||
_max_distance_from_start_index = 0;
|
||||
for (int i = 0; i < _capacity; i += 1) {
|
||||
_entries[i].used = false;
|
||||
}
|
||||
}
|
||||
|
||||
void internal_put(K key, V value) {
|
||||
int start_index = key_to_index(key);
|
||||
for (int roll_over = 0, distance_from_start_index = 0;
|
||||
roll_over < _capacity; roll_over += 1, distance_from_start_index += 1)
|
||||
{
|
||||
int index = (start_index + roll_over) % _capacity;
|
||||
Entry *entry = &_entries[index];
|
||||
|
||||
if (entry->used && !EqualFn(entry->key, key)) {
|
||||
if (entry->distance_from_start_index < distance_from_start_index) {
|
||||
// robin hood to the rescue
|
||||
Entry tmp = *entry;
|
||||
if (distance_from_start_index > _max_distance_from_start_index)
|
||||
_max_distance_from_start_index = distance_from_start_index;
|
||||
*entry = {
|
||||
key,
|
||||
value,
|
||||
true,
|
||||
distance_from_start_index,
|
||||
};
|
||||
key = tmp.key;
|
||||
value = tmp.value;
|
||||
distance_from_start_index = tmp.distance_from_start_index;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry->used) {
|
||||
// adding an entry. otherwise overwriting old value with
|
||||
// same key
|
||||
_size += 1;
|
||||
}
|
||||
|
||||
if (distance_from_start_index > _max_distance_from_start_index)
|
||||
_max_distance_from_start_index = distance_from_start_index;
|
||||
*entry = {
|
||||
key,
|
||||
value,
|
||||
true,
|
||||
distance_from_start_index,
|
||||
};
|
||||
return;
|
||||
}
|
||||
zig_panic("put into a full HashMap");
|
||||
}
|
||||
|
||||
|
||||
Entry *internal_get(const K &key) const {
|
||||
int start_index = key_to_index(key);
|
||||
for (int roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {
|
||||
int index = (start_index + roll_over) % _capacity;
|
||||
Entry *entry = &_entries[index];
|
||||
|
||||
if (!entry->used)
|
||||
return NULL;
|
||||
|
||||
if (EqualFn(entry->key, key))
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int key_to_index(const K &key) const {
|
||||
return (int)(HashFunction(key) % ((uint32_t)_capacity));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEM_LIST_HPP
|
||||
#define ZIG_MEM_LIST_HPP
|
||||
|
||||
#include "mem.hpp"
|
||||
|
||||
namespace mem {
|
||||
|
||||
template<typename T>
|
||||
struct List {
|
||||
void deinit(Allocator& allocator) {
|
||||
allocator.deallocate<T>(items, capacity);
|
||||
}
|
||||
|
||||
void append(Allocator& allocator, const T& item) {
|
||||
ensure_capacity(allocator, length + 1);
|
||||
items[length++] = item;
|
||||
}
|
||||
|
||||
// remember that the pointer to this item is invalid after you
|
||||
// modify the length of the list
|
||||
const T & at(size_t index) const {
|
||||
assert(index != SIZE_MAX);
|
||||
assert(index < length);
|
||||
return items[index];
|
||||
}
|
||||
|
||||
T & at(size_t index) {
|
||||
assert(index != SIZE_MAX);
|
||||
assert(index < length);
|
||||
return items[index];
|
||||
}
|
||||
|
||||
T pop() {
|
||||
assert(length >= 1);
|
||||
return items[--length];
|
||||
}
|
||||
|
||||
T *add_one() {
|
||||
resize(length + 1);
|
||||
return &last();
|
||||
}
|
||||
|
||||
const T & last() const {
|
||||
assert(length >= 1);
|
||||
return items[length - 1];
|
||||
}
|
||||
|
||||
T & last() {
|
||||
assert(length >= 1);
|
||||
return items[length - 1];
|
||||
}
|
||||
|
||||
void resize(Allocator& allocator, size_t new_length) {
|
||||
assert(new_length != SIZE_MAX);
|
||||
ensure_capacity(allocator, new_length);
|
||||
length = new_length;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
void ensure_capacity(Allocator& allocator, size_t new_capacity) {
|
||||
if (capacity >= new_capacity)
|
||||
return;
|
||||
|
||||
size_t better_capacity = capacity;
|
||||
do {
|
||||
better_capacity = better_capacity * 5 / 2 + 8;
|
||||
} while (better_capacity < new_capacity);
|
||||
|
||||
items = allocator.reallocate_nonzero<T>(items, capacity, better_capacity);
|
||||
capacity = better_capacity;
|
||||
}
|
||||
|
||||
T swap_remove(size_t index) {
|
||||
if (length - 1 == index) return pop();
|
||||
|
||||
assert(index != SIZE_MAX);
|
||||
assert(index < length);
|
||||
|
||||
T old_item = items[index];
|
||||
items[index] = pop();
|
||||
return old_item;
|
||||
}
|
||||
|
||||
T *items{nullptr};
|
||||
size_t length{0};
|
||||
size_t capacity{0};
|
||||
};
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
|
||||
#include "mem.hpp"
|
||||
#include "mem_list.hpp"
|
||||
#include "mem_profile.hpp"
|
||||
#include "heap.hpp"
|
||||
|
||||
namespace mem {
|
||||
|
||||
void Profile::init(const char *name, const char *kind) {
|
||||
this->name = name;
|
||||
this->kind = kind;
|
||||
this->usage_table.init(heap::bootstrap_allocator, 1024);
|
||||
}
|
||||
|
||||
void Profile::deinit() {
|
||||
assert(this->name != nullptr);
|
||||
if (mem::report_print)
|
||||
this->print_report();
|
||||
this->usage_table.deinit(heap::bootstrap_allocator);
|
||||
this->name = nullptr;
|
||||
}
|
||||
|
||||
void Profile::record_alloc(const TypeInfo &info, size_t count) {
|
||||
if (count == 0) return;
|
||||
auto existing_entry = this->usage_table.put_unique(
|
||||
heap::bootstrap_allocator,
|
||||
UsageKey{info.name_ptr, info.name_len},
|
||||
Entry{info, 1, count, 0, 0} );
|
||||
if (existing_entry != nullptr) {
|
||||
assert(existing_entry->value.info.size == info.size); // allocated name does not match type
|
||||
existing_entry->value.alloc.calls += 1;
|
||||
existing_entry->value.alloc.objects += count;
|
||||
}
|
||||
}
|
||||
|
||||
void Profile::record_dealloc(const TypeInfo &info, size_t count) {
|
||||
if (count == 0) return;
|
||||
auto existing_entry = this->usage_table.maybe_get(UsageKey{info.name_ptr, info.name_len});
|
||||
if (existing_entry == nullptr) {
|
||||
fprintf(stderr, "deallocated name '");
|
||||
for (size_t i = 0; i < info.name_len; ++i)
|
||||
fputc(info.name_ptr[i], stderr);
|
||||
zig_panic("' (size %zu) not found in allocated table; compromised memory usage stats", info.size);
|
||||
}
|
||||
if (existing_entry->value.info.size != info.size) {
|
||||
fprintf(stderr, "deallocated name '");
|
||||
for (size_t i = 0; i < info.name_len; ++i)
|
||||
fputc(info.name_ptr[i], stderr);
|
||||
zig_panic("' does not match expected type size %zu", info.size);
|
||||
}
|
||||
assert(existing_entry->value.alloc.calls - existing_entry->value.dealloc.calls > 0);
|
||||
assert(existing_entry->value.alloc.objects - existing_entry->value.dealloc.objects >= count);
|
||||
existing_entry->value.dealloc.calls += 1;
|
||||
existing_entry->value.dealloc.objects += count;
|
||||
}
|
||||
|
||||
static size_t entry_remain_total_bytes(const Profile::Entry *entry) {
|
||||
return (entry->alloc.objects - entry->dealloc.objects) * entry->info.size;
|
||||
}
|
||||
|
||||
static int entry_compare(const void *a, const void *b) {
|
||||
size_t total_a = entry_remain_total_bytes(*reinterpret_cast<Profile::Entry *const *>(a));
|
||||
size_t total_b = entry_remain_total_bytes(*reinterpret_cast<Profile::Entry *const *>(b));
|
||||
if (total_a > total_b)
|
||||
return -1;
|
||||
if (total_a < total_b)
|
||||
return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
void Profile::print_report(FILE *file) {
|
||||
if (!file) {
|
||||
file = report_file;
|
||||
if (!file)
|
||||
file = stderr;
|
||||
}
|
||||
fprintf(file, "\n--- MEMORY PROFILE REPORT [%s]: %s ---\n", this->kind, this->name);
|
||||
|
||||
List<const Entry *> list;
|
||||
auto it = this->usage_table.entry_iterator();
|
||||
for (;;) {
|
||||
auto entry = it.next();
|
||||
if (!entry)
|
||||
break;
|
||||
list.append(heap::bootstrap_allocator, &entry->value);
|
||||
}
|
||||
|
||||
qsort(list.items, list.length, sizeof(const Entry *), entry_compare);
|
||||
|
||||
size_t total_bytes_alloc = 0;
|
||||
size_t total_bytes_dealloc = 0;
|
||||
|
||||
size_t total_calls_alloc = 0;
|
||||
size_t total_calls_dealloc = 0;
|
||||
|
||||
for (size_t i = 0; i < list.length; i += 1) {
|
||||
const Entry *entry = list.at(i);
|
||||
fprintf(file, " ");
|
||||
for (size_t j = 0; j < entry->info.name_len; ++j)
|
||||
fputc(entry->info.name_ptr[j], file);
|
||||
fprintf(file, ": %zu bytes each", entry->info.size);
|
||||
|
||||
fprintf(file, ", alloc{ %zu calls, %zu objects, total ", entry->alloc.calls, entry->alloc.objects);
|
||||
const auto alloc_num_bytes = entry->alloc.objects * entry->info.size;
|
||||
zig_pretty_print_bytes(file, alloc_num_bytes);
|
||||
|
||||
fprintf(file, " }, dealloc{ %zu calls, %zu objects, total ", entry->dealloc.calls, entry->dealloc.objects);
|
||||
const auto dealloc_num_bytes = entry->dealloc.objects * entry->info.size;
|
||||
zig_pretty_print_bytes(file, dealloc_num_bytes);
|
||||
|
||||
fprintf(file, " }, remain{ %zu calls, %zu objects, total ",
|
||||
entry->alloc.calls - entry->dealloc.calls,
|
||||
entry->alloc.objects - entry->dealloc.objects );
|
||||
const auto remain_num_bytes = alloc_num_bytes - dealloc_num_bytes;
|
||||
zig_pretty_print_bytes(file, remain_num_bytes);
|
||||
|
||||
fprintf(file, " }\n");
|
||||
|
||||
total_bytes_alloc += alloc_num_bytes;
|
||||
total_bytes_dealloc += dealloc_num_bytes;
|
||||
|
||||
total_calls_alloc += entry->alloc.calls;
|
||||
total_calls_dealloc += entry->dealloc.calls;
|
||||
}
|
||||
|
||||
fprintf(file, "\n Total bytes allocated: ");
|
||||
zig_pretty_print_bytes(file, total_bytes_alloc);
|
||||
fprintf(file, ", deallocated: ");
|
||||
zig_pretty_print_bytes(file, total_bytes_dealloc);
|
||||
fprintf(file, ", remaining: ");
|
||||
zig_pretty_print_bytes(file, total_bytes_alloc - total_bytes_dealloc);
|
||||
|
||||
fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n",
|
||||
total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc));
|
||||
|
||||
list.deinit(heap::bootstrap_allocator);
|
||||
}
|
||||
|
||||
uint32_t Profile::usage_hash(UsageKey key) {
|
||||
// FNV 32-bit hash
|
||||
uint32_t h = 2166136261;
|
||||
for (size_t i = 0; i < key.name_len; ++i) {
|
||||
h = h ^ key.name_ptr[i];
|
||||
h = h * 16777619;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
bool Profile::usage_equal(UsageKey a, UsageKey b) {
|
||||
return memcmp(a.name_ptr, b.name_ptr, a.name_len > b.name_len ? a.name_len : b.name_len) == 0;
|
||||
}
|
||||
|
||||
void InternCounters::print_report(FILE *file) {
|
||||
if (!file) {
|
||||
file = report_file;
|
||||
if (!file)
|
||||
file = stderr;
|
||||
}
|
||||
fprintf(file, "\n--- IR INTERNING REPORT ---\n");
|
||||
fprintf(file, " undefined: interned %zu times\n", intern_counters.x_undefined);
|
||||
fprintf(file, " void: interned %zu times\n", intern_counters.x_void);
|
||||
fprintf(file, " null: interned %zu times\n", intern_counters.x_null);
|
||||
fprintf(file, " unreachable: interned %zu times\n", intern_counters.x_unreachable);
|
||||
fprintf(file, " zero_byte: interned %zu times\n", intern_counters.zero_byte);
|
||||
}
|
||||
|
||||
InternCounters intern_counters;
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEM_PROFILE_HPP
|
||||
#define ZIG_MEM_PROFILE_HPP
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mem.hpp"
|
||||
#include "mem_hash_map.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
namespace mem {
|
||||
|
||||
struct Profile {
|
||||
void init(const char *name, const char *kind);
|
||||
void deinit();
|
||||
|
||||
void record_alloc(const TypeInfo &info, size_t count);
|
||||
void record_dealloc(const TypeInfo &info, size_t count);
|
||||
|
||||
void print_report(FILE *file = nullptr);
|
||||
|
||||
struct Entry {
|
||||
TypeInfo info;
|
||||
|
||||
struct Use {
|
||||
size_t calls;
|
||||
size_t objects;
|
||||
} alloc, dealloc;
|
||||
};
|
||||
|
||||
private:
|
||||
const char *name;
|
||||
const char *kind;
|
||||
|
||||
struct UsageKey {
|
||||
const char *name_ptr;
|
||||
size_t name_len;
|
||||
};
|
||||
|
||||
static uint32_t usage_hash(UsageKey key);
|
||||
static bool usage_equal(UsageKey a, UsageKey b);
|
||||
|
||||
HashMap<UsageKey, Entry, usage_hash, usage_equal> usage_table;
|
||||
};
|
||||
|
||||
struct InternCounters {
|
||||
size_t x_undefined;
|
||||
size_t x_void;
|
||||
size_t x_null;
|
||||
size_t x_unreachable;
|
||||
size_t zero_byte;
|
||||
|
||||
void print_report(FILE *file = nullptr);
|
||||
};
|
||||
|
||||
extern InternCounters intern_counters;
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEM_TYPE_INFO_HPP
|
||||
#define ZIG_MEM_TYPE_INFO_HPP
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef ZIG_TYPE_INFO_IMPLEMENTATION
|
||||
# ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
# define ZIG_TYPE_INFO_IMPLEMENTATION 1
|
||||
# else
|
||||
# define ZIG_TYPE_INFO_IMPLEMENTATION 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace mem {
|
||||
|
||||
#if ZIG_TYPE_INFO_IMPLEMENTATION == 0
|
||||
|
||||
struct TypeInfo {
|
||||
size_t size;
|
||||
size_t alignment;
|
||||
|
||||
template <typename T>
|
||||
static constexpr TypeInfo make() {
|
||||
return {sizeof(T), alignof(T)};
|
||||
}
|
||||
};
|
||||
|
||||
#elif ZIG_TYPE_INFO_IMPLEMENTATION == 1
|
||||
|
||||
//
|
||||
// A non-portable way to get a human-readable type-name compatible with
|
||||
// non-RTTI C++ compiler mode; eg. `-fno-rtti`.
|
||||
//
|
||||
// Minimum requirements are c++11 and a compiler that has a constant for the
|
||||
// current function's decorated name whereby a template-type name can be
|
||||
// computed. eg. `__PRETTY_FUNCTION__` or `__FUNCSIG__`.
|
||||
//
|
||||
// given the following snippet:
|
||||
//
|
||||
// | #include <stdio.h>
|
||||
// |
|
||||
// | struct Top {};
|
||||
// | namespace mynamespace {
|
||||
// | using custom = unsigned int;
|
||||
// | struct Foo {
|
||||
// | struct Bar {};
|
||||
// | };
|
||||
// | };
|
||||
// |
|
||||
// | template <typename T>
|
||||
// | void foobar() {
|
||||
// | #ifdef _MSC_VER
|
||||
// | fprintf(stderr, "--> %s\n", __FUNCSIG__);
|
||||
// | #else
|
||||
// | fprintf(stderr, "--> %s\n", __PRETTY_FUNCTION__);
|
||||
// | #endif
|
||||
// | }
|
||||
// |
|
||||
// | int main() {
|
||||
// | foobar<Top>();
|
||||
// | foobar<unsigned int>();
|
||||
// | foobar<mynamespace::custom>();
|
||||
// | foobar<mynamespace::Foo*>();
|
||||
// | foobar<mynamespace::Foo::Bar*>();
|
||||
// | }
|
||||
//
|
||||
// gcc 9.2.0 produces:
|
||||
// --> void foobar() [with T = Top]
|
||||
// --> void foobar() [with T = unsigned int]
|
||||
// --> void foobar() [with T = unsigned int]
|
||||
// --> void foobar() [with T = mynamespace::Foo*]
|
||||
// --> void foobar() [with T = mynamespace::Foo::Bar*]
|
||||
//
|
||||
// xcode 11.3.1/clang produces:
|
||||
// --> void foobar() [T = Top]
|
||||
// --> void foobar() [T = unsigned int]
|
||||
// --> void foobar() [T = unsigned int]
|
||||
// --> void foobar() [T = mynamespace::Foo *]
|
||||
// --> void foobar() [T = mynamespace::Foo::Bar *]
|
||||
//
|
||||
// VStudio 2019 16.5.0/msvc produces:
|
||||
// --> void __cdecl foobar<struct Top>(void)
|
||||
// --> void __cdecl foobar<unsigned int>(void)
|
||||
// --> void __cdecl foobar<unsigned int>(void)
|
||||
// --> void __cdecl foobar<structmynamespace::Foo*>(void)
|
||||
// --> void __cdecl foobar<structmynamespace::Foo::Bar*>(void)
|
||||
//
|
||||
struct TypeInfo {
|
||||
const char *name_ptr;
|
||||
size_t name_len;
|
||||
size_t size;
|
||||
size_t alignment;
|
||||
|
||||
static constexpr TypeInfo to_type_info(const char *str, size_t start, size_t end, size_t size, size_t alignment) {
|
||||
return TypeInfo{str + start, end - start, size, alignment};
|
||||
}
|
||||
|
||||
static constexpr size_t index_of(const char *str, char c) {
|
||||
return *str == c ? 0 : 1 + index_of(str + 1, c);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static constexpr const char *decorated_name() {
|
||||
#ifdef _MSC_VER
|
||||
return __FUNCSIG__;
|
||||
#else
|
||||
return __PRETTY_FUNCTION__;
|
||||
#endif
|
||||
}
|
||||
|
||||
static constexpr TypeInfo extract(const char *decorated, size_t size, size_t alignment) {
|
||||
#ifdef _MSC_VER
|
||||
return to_type_info(decorated, index_of(decorated, '<') + 1, index_of(decorated, '>'), size, alignment);
|
||||
#else
|
||||
return to_type_info(decorated, index_of(decorated, '=') + 2, index_of(decorated, ']'), size, alignment);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static constexpr TypeInfo make() {
|
||||
return TypeInfo::extract(TypeInfo::decorated_name<T>(), sizeof(T), alignof(T));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ZIG_TYPE_INFO_IMPLEMENTATION
|
||||
|
||||
} // namespace mem
|
||||
|
||||
#endif
|
||||
@@ -1,150 +0,0 @@
|
||||
#include "memory_profiling.hpp"
|
||||
#include "hash_map.hpp"
|
||||
#include "list.hpp"
|
||||
#include "util.hpp"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
|
||||
MemprofInternCount memprof_intern_count;
|
||||
|
||||
static bool str_eql_str(const char *a, const char *b) {
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
static uint32_t str_hash(const char *s) {
|
||||
// FNV 32-bit hash
|
||||
uint32_t h = 2166136261;
|
||||
for (; *s; s += 1) {
|
||||
h = h ^ *s;
|
||||
h = h * 16777619;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
struct CountAndSize {
|
||||
size_t item_count;
|
||||
size_t type_size;
|
||||
};
|
||||
|
||||
ZigList<const char *> unknown_names = {};
|
||||
HashMap<const char *, CountAndSize, str_hash, str_eql_str> usage_table = {};
|
||||
bool table_active = false;
|
||||
|
||||
static const char *get_default_name(const char *name_or_null, size_t type_size) {
|
||||
if (name_or_null != nullptr) return name_or_null;
|
||||
if (type_size >= unknown_names.length) {
|
||||
table_active = false;
|
||||
while (type_size >= unknown_names.length) {
|
||||
unknown_names.append(nullptr);
|
||||
}
|
||||
table_active = true;
|
||||
}
|
||||
if (unknown_names.at(type_size) == nullptr) {
|
||||
char buf[100];
|
||||
sprintf(buf, "Unknown_%zu%c", type_size, 0);
|
||||
unknown_names.at(type_size) = strdup(buf);
|
||||
}
|
||||
return unknown_names.at(type_size);
|
||||
}
|
||||
|
||||
void memprof_alloc(const char *name, size_t count, size_t type_size) {
|
||||
if (!table_active) return;
|
||||
if (count == 0) return;
|
||||
// temporarily disable during table put
|
||||
table_active = false;
|
||||
name = get_default_name(name, type_size);
|
||||
auto existing_entry = usage_table.put_unique(name, {count, type_size});
|
||||
if (existing_entry != nullptr) {
|
||||
assert(existing_entry->value.type_size == type_size); // allocated name does not match type
|
||||
existing_entry->value.item_count += count;
|
||||
}
|
||||
table_active = true;
|
||||
}
|
||||
|
||||
void memprof_dealloc(const char *name, size_t count, size_t type_size) {
|
||||
if (!table_active) return;
|
||||
if (count == 0) return;
|
||||
name = get_default_name(name, type_size);
|
||||
auto existing_entry = usage_table.maybe_get(name);
|
||||
if (existing_entry == nullptr) {
|
||||
zig_panic("deallocated name '%s' (size %zu) not found in allocated table; compromised memory usage stats",
|
||||
name, type_size);
|
||||
}
|
||||
if (existing_entry->value.type_size != type_size) {
|
||||
zig_panic("deallocated name '%s' does not match expected type size %zu", name, type_size);
|
||||
}
|
||||
existing_entry->value.item_count -= count;
|
||||
}
|
||||
|
||||
void memprof_init(void) {
|
||||
usage_table.init(1024);
|
||||
table_active = true;
|
||||
}
|
||||
|
||||
struct MemItem {
|
||||
const char *type_name;
|
||||
CountAndSize count_and_size;
|
||||
};
|
||||
|
||||
static size_t get_bytes(const MemItem *item) {
|
||||
return item->count_and_size.item_count * item->count_and_size.type_size;
|
||||
}
|
||||
|
||||
static int compare_bytes_desc(const void *a, const void *b) {
|
||||
size_t size_a = get_bytes((const MemItem *)(a));
|
||||
size_t size_b = get_bytes((const MemItem *)(b));
|
||||
if (size_a > size_b)
|
||||
return -1;
|
||||
if (size_a < size_b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memprof_dump_stats(FILE *file) {
|
||||
assert(table_active);
|
||||
// disable modifications from this function
|
||||
table_active = false;
|
||||
|
||||
ZigList<MemItem> list = {};
|
||||
|
||||
auto it = usage_table.entry_iterator();
|
||||
for (;;) {
|
||||
auto *entry = it.next();
|
||||
if (!entry)
|
||||
break;
|
||||
|
||||
list.append({entry->key, entry->value});
|
||||
}
|
||||
|
||||
qsort(list.items, list.length, sizeof(MemItem), compare_bytes_desc);
|
||||
|
||||
size_t total_bytes_used = 0;
|
||||
|
||||
for (size_t i = 0; i < list.length; i += 1) {
|
||||
const MemItem *item = &list.at(i);
|
||||
fprintf(file, "%s: %zu items, %zu bytes each, total ", item->type_name,
|
||||
item->count_and_size.item_count, item->count_and_size.type_size);
|
||||
size_t bytes = get_bytes(item);
|
||||
zig_pretty_print_bytes(file, bytes);
|
||||
fprintf(file, "\n");
|
||||
|
||||
total_bytes_used += bytes;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Total bytes used: ");
|
||||
zig_pretty_print_bytes(file, total_bytes_used);
|
||||
fprintf(file, "\n");
|
||||
|
||||
list.deinit();
|
||||
table_active = true;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "undefined: interned %zu times\n", memprof_intern_count.x_undefined);
|
||||
fprintf(stderr, "void: interned %zu times\n", memprof_intern_count.x_void);
|
||||
fprintf(stderr, "null: interned %zu times\n", memprof_intern_count.x_null);
|
||||
fprintf(stderr, "unreachable: interned %zu times\n", memprof_intern_count.x_unreachable);
|
||||
fprintf(stderr, "zero_byte: interned %zu times\n", memprof_intern_count.zero_byte);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_MEMORY_PROFILING_HPP
|
||||
#define ZIG_MEMORY_PROFILING_HPP
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct MemprofInternCount {
|
||||
size_t x_undefined;
|
||||
size_t x_void;
|
||||
size_t x_null;
|
||||
size_t x_unreachable;
|
||||
size_t zero_byte;
|
||||
};
|
||||
extern MemprofInternCount memprof_intern_count;
|
||||
|
||||
void memprof_init(void);
|
||||
|
||||
void memprof_alloc(const char *name, size_t item_count, size_t type_size);
|
||||
void memprof_dealloc(const char *name, size_t item_count, size_t type_size);
|
||||
|
||||
void memprof_dump_stats(FILE *file);
|
||||
#endif
|
||||
+7
-7
@@ -107,7 +107,7 @@ static void populate_termination(Termination *term, int status) {
|
||||
}
|
||||
|
||||
static void os_spawn_process_posix(ZigList<const char *> &args, Termination *term) {
|
||||
const char **argv = allocate<const char *>(args.length + 1);
|
||||
const char **argv = heap::c_allocator.allocate<const char *>(args.length + 1);
|
||||
for (size_t i = 0; i < args.length; i += 1) {
|
||||
argv[i] = args.at(i);
|
||||
}
|
||||
@@ -688,7 +688,7 @@ static Buf os_path_resolve_posix(Buf **paths_ptr, size_t paths_len) {
|
||||
|
||||
if (have_abs) {
|
||||
result_len = max_size;
|
||||
result_ptr = allocate_nonzero<uint8_t>(result_len);
|
||||
result_ptr = heap::c_allocator.allocate_nonzero<uint8_t>(result_len);
|
||||
} else {
|
||||
Buf cwd = BUF_INIT;
|
||||
int err;
|
||||
@@ -696,7 +696,7 @@ static Buf os_path_resolve_posix(Buf **paths_ptr, size_t paths_len) {
|
||||
zig_panic("get cwd failed");
|
||||
}
|
||||
result_len = max_size + buf_len(&cwd) + 1;
|
||||
result_ptr = allocate_nonzero<uint8_t>(result_len);
|
||||
result_ptr = heap::c_allocator.allocate_nonzero<uint8_t>(result_len);
|
||||
memcpy(result_ptr, buf_ptr(&cwd), buf_len(&cwd));
|
||||
result_index += buf_len(&cwd);
|
||||
}
|
||||
@@ -816,7 +816,7 @@ static Error os_exec_process_posix(ZigList<const char *> &args,
|
||||
if (dup2(stderr_pipe[1], STDERR_FILENO) == -1)
|
||||
zig_panic("dup2 failed");
|
||||
|
||||
const char **argv = allocate<const char *>(args.length + 1);
|
||||
const char **argv = heap::c_allocator.allocate<const char *>(args.length + 1);
|
||||
argv[args.length] = nullptr;
|
||||
for (size_t i = 0; i < args.length; i += 1) {
|
||||
argv[i] = args.at(i);
|
||||
@@ -1134,7 +1134,7 @@ static bool is_stderr_cyg_pty(void) {
|
||||
if (stderr_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
|
||||
const int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
|
||||
FILE_NAME_INFO *nameinfo;
|
||||
WCHAR *p = NULL;
|
||||
|
||||
@@ -1142,7 +1142,7 @@ static bool is_stderr_cyg_pty(void) {
|
||||
if (GetFileType(stderr_handle) != FILE_TYPE_PIPE) {
|
||||
return 0;
|
||||
}
|
||||
nameinfo = (FILE_NAME_INFO *)allocate<char>(size);
|
||||
nameinfo = reinterpret_cast<FILE_NAME_INFO *>(heap::c_allocator.allocate<char>(size));
|
||||
if (nameinfo == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1179,7 +1179,7 @@ static bool is_stderr_cyg_pty(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
free(nameinfo);
|
||||
heap::c_allocator.deallocate(reinterpret_cast<char *>(nameinfo), size);
|
||||
return (p != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -147,7 +147,7 @@ static void ast_invalid_token_error(ParseContext *pc, Token *token) {
|
||||
}
|
||||
|
||||
static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
|
||||
AstNode *node = allocate<AstNode>(1, "AstNode");
|
||||
AstNode *node = heap::c_allocator.create<AstNode>();
|
||||
node->type = type;
|
||||
node->owner = pc->owner;
|
||||
return node;
|
||||
@@ -1966,7 +1966,7 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
|
||||
|
||||
expect_token(pc, TokenIdRParen);
|
||||
|
||||
AsmOutput *res = allocate<AsmOutput>(1);
|
||||
AsmOutput *res = heap::c_allocator.create<AsmOutput>();
|
||||
res->asm_symbolic_name = token_buf(sym_name);
|
||||
res->constraint = token_buf(str);
|
||||
res->variable_name = token_buf(var_name);
|
||||
@@ -2003,7 +2003,7 @@ static AsmInput *ast_parse_asm_input_item(ParseContext *pc) {
|
||||
AstNode *expr = ast_expect(pc, ast_parse_expr);
|
||||
expect_token(pc, TokenIdRParen);
|
||||
|
||||
AsmInput *res = allocate<AsmInput>(1);
|
||||
AsmInput *res = heap::c_allocator.create<AsmInput>();
|
||||
res->asm_symbolic_name = token_buf(sym_name);
|
||||
res->constraint = token_buf(constraint);
|
||||
res->expr = expr;
|
||||
|
||||
+1
-1
@@ -524,7 +524,7 @@ void get_native_target(ZigTarget *target) {
|
||||
target->abi = target_default_abi(target->arch, target->os);
|
||||
}
|
||||
if (target_is_glibc(target)) {
|
||||
target->glibc_version = allocate<ZigGLibCVersion>(1);
|
||||
target->glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
|
||||
target_init_default_glibc_version(target);
|
||||
#ifdef ZIG_OS_LINUX
|
||||
Error err;
|
||||
|
||||
+2
-2
@@ -397,10 +397,10 @@ static void invalid_char_error(Tokenize *t, uint8_t c) {
|
||||
void tokenize(Buf *buf, Tokenization *out) {
|
||||
Tokenize t = {0};
|
||||
t.out = out;
|
||||
t.tokens = out->tokens = allocate<ZigList<Token>>(1);
|
||||
t.tokens = out->tokens = heap::c_allocator.create<ZigList<Token>>();
|
||||
t.buf = buf;
|
||||
|
||||
out->line_offsets = allocate<ZigList<size_t>>(1);
|
||||
out->line_offsets = heap::c_allocator.create<ZigList<size_t>>();
|
||||
out->line_offsets->append(0);
|
||||
|
||||
// Skip the UTF-8 BOM if present
|
||||
|
||||
+2
-2
@@ -101,7 +101,7 @@ Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_
|
||||
const char *cpu_name, const char *cpu_features)
|
||||
{
|
||||
if (zig_triple == nullptr) {
|
||||
Stage2CpuFeatures *result = allocate<Stage2CpuFeatures>(1, "Stage2CpuFeatures");
|
||||
Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>();
|
||||
result->llvm_cpu_name = ZigLLVMGetHostCPUName();
|
||||
result->llvm_cpu_features = ZigLLVMGetNativeFeatures();
|
||||
result->builtin_str = "arch.getBaselineCpuFeatures();\n";
|
||||
@@ -110,7 +110,7 @@ Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_
|
||||
return ErrorNone;
|
||||
}
|
||||
if (cpu_name == nullptr && cpu_features == nullptr) {
|
||||
Stage2CpuFeatures *result = allocate<Stage2CpuFeatures>(1, "Stage2CpuFeatures");
|
||||
Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>();
|
||||
result->builtin_str = "arch.getBaselineCpuFeatures();\n";
|
||||
result->cache_hash = "\n\n";
|
||||
*out = result;
|
||||
|
||||
+5
-127
@@ -8,69 +8,19 @@
|
||||
#ifndef ZIG_UTIL_HPP
|
||||
#define ZIG_UTIL_HPP
|
||||
|
||||
#include "memory_profiling.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
#define ATTRIBUTE_COLD __declspec(noinline)
|
||||
#define ATTRIBUTE_PRINTF(a, b)
|
||||
#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
|
||||
#define ATTRIBUTE_NORETURN __declspec(noreturn)
|
||||
#define ATTRIBUTE_MUST_USE
|
||||
|
||||
#define BREAKPOINT __debugbreak()
|
||||
|
||||
#else
|
||||
|
||||
#define ATTRIBUTE_COLD __attribute__((cold))
|
||||
#define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b)))
|
||||
#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
|
||||
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
|
||||
#define ATTRIBUTE_MUST_USE __attribute__((warn_unused_result))
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define BREAKPOINT __debugbreak()
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
#define BREAKPOINT __asm__ volatile("int $0x03");
|
||||
#elif defined(__clang__)
|
||||
#define BREAKPOINT __builtin_debugtrap()
|
||||
#elif defined(__GNUC__)
|
||||
#define BREAKPOINT __builtin_trap()
|
||||
#else
|
||||
#include <signal.h>
|
||||
#define BREAKPOINT raise(SIGTRAP)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ATTRIBUTE_COLD
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(1, 2)
|
||||
void zig_panic(const char *format, ...);
|
||||
|
||||
static inline void zig_assert(bool ok, const char *file, int line, const char *func) {
|
||||
if (!ok) {
|
||||
zig_panic("Assertion failed at %s:%d in %s. This is a bug in the Zig compiler.", file, line, func);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#define zig_unreachable() zig_panic("Unreachable at %s:%d in %s. This is a bug in the Zig compiler.", __FILE__, __LINE__, __func__)
|
||||
|
||||
// Assertions in stage1 are always on, and they call zig @panic.
|
||||
#undef assert
|
||||
#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)
|
||||
#include "config.h"
|
||||
#include "util_base.hpp"
|
||||
#include "heap.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
static inline int clzll(unsigned long long mask) {
|
||||
@@ -107,78 +57,6 @@ static inline int ctzll(unsigned long long mask) {
|
||||
#define ctzll(x) __builtin_ctzll(x)
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T>
|
||||
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count, const char *name = nullptr) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_alloc(name, count, sizeof(T));
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (count == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
|
||||
if (!ptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count, const char *name = nullptr) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_alloc(name, count, sizeof(T));
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (count == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
|
||||
if (!ptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T *reallocate(T *old, size_t old_count, size_t new_count, const char *name = nullptr) {
|
||||
T *ptr = reallocate_nonzero(old, old_count, new_count);
|
||||
if (new_count > old_count) {
|
||||
memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count, const char *name = nullptr) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_dealloc(name, old_count, sizeof(T));
|
||||
memprof_alloc(name, new_count, sizeof(T));
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
// make behavior when size == 0 portable
|
||||
if (new_count == 0 && old == nullptr)
|
||||
return nullptr;
|
||||
#endif
|
||||
T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
|
||||
if (!ptr)
|
||||
zig_panic("allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void deallocate(T *old, size_t count, const char *name = nullptr) {
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_dealloc(name, count, sizeof(T));
|
||||
#endif
|
||||
free(old);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void destroy(T *old, const char *name = nullptr) {
|
||||
return deallocate(old, 1, name);
|
||||
}
|
||||
|
||||
template <typename T, size_t n>
|
||||
constexpr size_t array_length(const T (&)[n]) {
|
||||
return n;
|
||||
@@ -293,7 +171,7 @@ struct Slice {
|
||||
}
|
||||
|
||||
static inline Slice<T> alloc(size_t n) {
|
||||
return {allocate_nonzero<T>(n), n};
|
||||
return {heap::c_allocator.allocate_nonzero<T>(n), n};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_UTIL_BASE_HPP
|
||||
#define ZIG_UTIL_BASE_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#define ATTRIBUTE_COLD __declspec(noinline)
|
||||
#define ATTRIBUTE_PRINTF(a, b)
|
||||
#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
|
||||
#define ATTRIBUTE_NORETURN __declspec(noreturn)
|
||||
#define ATTRIBUTE_MUST_USE
|
||||
|
||||
#define BREAKPOINT __debugbreak()
|
||||
|
||||
#else
|
||||
|
||||
#define ATTRIBUTE_COLD __attribute__((cold))
|
||||
#define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b)))
|
||||
#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
|
||||
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
|
||||
#define ATTRIBUTE_MUST_USE __attribute__((warn_unused_result))
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define BREAKPOINT __debugbreak()
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
#define BREAKPOINT __asm__ volatile("int $0x03");
|
||||
#elif defined(__clang__)
|
||||
#define BREAKPOINT __builtin_debugtrap()
|
||||
#elif defined(__GNUC__)
|
||||
#define BREAKPOINT __builtin_trap()
|
||||
#else
|
||||
#include <signal.h>
|
||||
#define BREAKPOINT raise(SIGTRAP)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ATTRIBUTE_COLD
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(1, 2)
|
||||
void zig_panic(const char *format, ...);
|
||||
|
||||
static inline void zig_assert(bool ok, const char *file, int line, const char *func) {
|
||||
if (!ok) {
|
||||
zig_panic("Assertion failed at %s:%d in %s. This is a bug in the Zig compiler.", file, line, func);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#define zig_unreachable() zig_panic("Unreachable at %s:%d in %s. This is a bug in the Zig compiler.", __FILE__, __LINE__, __func__)
|
||||
|
||||
// Assertions in stage1 are always on, and they call zig @panic.
|
||||
#undef assert
|
||||
#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,22 @@ const builtin = @import("builtin");
|
||||
const Target = @import("std").Target;
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.addTest("duplicate field in anonymous struct literal",
|
||||
\\export fn entry() void {
|
||||
\\ const anon = .{
|
||||
\\ .inner = .{
|
||||
\\ .a = .{
|
||||
\\ .something = "text",
|
||||
\\ },
|
||||
\\ .a = .{},
|
||||
\\ },
|
||||
\\ };
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:7:13: error: duplicate field",
|
||||
"tmp.zig:4:13: note: other field here",
|
||||
});
|
||||
|
||||
cases.addTest("type mismatch in C prototype with varargs",
|
||||
\\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
|
||||
\\extern fn fn_decl(fmt: [*:0]u8, ...) void;
|
||||
|
||||
@@ -146,10 +146,10 @@ fn testAtomicStore() void {
|
||||
}
|
||||
|
||||
test "atomicrmw with floats" {
|
||||
if (builtin.arch == .aarch64 or
|
||||
builtin.arch == .arm or
|
||||
builtin.arch == .riscv64)
|
||||
return;
|
||||
if (builtin.arch == .aarch64 or builtin.arch == .arm or builtin.arch == .riscv64) {
|
||||
// https://github.com/ziglang/zig/issues/4457
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
testAtomicRmwFloat();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ test "allocation and looping over 3-byte integer" {
|
||||
expect(@sizeOf([1]u24) == 4);
|
||||
expect(@alignOf(u24) == 4);
|
||||
expect(@alignOf([1]u24) == 4);
|
||||
var buffer: [100]u8 = undefined;
|
||||
const a = &std.heap.FixedBufferAllocator.init(&buffer).allocator;
|
||||
|
||||
var x = a.alloc(u24, 2) catch unreachable;
|
||||
var x = try std.testing.allocator.alloc(u24, 2);
|
||||
defer std.testing.allocator.free(x);
|
||||
expect(x.len == 2);
|
||||
x[0] = 0xFFFFFF;
|
||||
x[1] = 0xFFFFFF;
|
||||
|
||||
@@ -764,3 +764,30 @@ test "variable initialization uses result locations properly with regards to the
|
||||
const x: i32 = if (b) 1 else 2;
|
||||
expect(x == 1);
|
||||
}
|
||||
|
||||
test "cast between [*c]T and ?[*:0]T on fn parameter" {
|
||||
const S = struct {
|
||||
const Handler = ?extern fn ([*c]const u8) void;
|
||||
fn addCallback(handler: Handler) void {}
|
||||
|
||||
fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}
|
||||
|
||||
fn doTheTest() void {
|
||||
addCallback(myCallback);
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "cast between C pointer with different but compatible types" {
|
||||
const S = struct {
|
||||
fn foo(arg: [*]c_ushort) u16 {
|
||||
return arg[0];
|
||||
}
|
||||
fn doTheTest() void {
|
||||
var x = [_]u16{ 4, 2, 1, 3 };
|
||||
expect(foo(@ptrCast([*]u16, &x)) == 4);
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const expect = std.testing.expect;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test "implicit cast vector to array - bool" {
|
||||
@@ -250,3 +251,29 @@ test "initialize vector which is a struct field" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "vector comparison operators" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
{
|
||||
const v1: @Vector(4, bool) = [_]bool{ true, false, true, false };
|
||||
const v2: @Vector(4, bool) = [_]bool{ false, true, false, true };
|
||||
expectEqual(@splat(4, true), v1 == v1);
|
||||
expectEqual(@splat(4, false), v1 == v2);
|
||||
expectEqual(@splat(4, true), v1 != v2);
|
||||
expectEqual(@splat(4, false), v2 != v2);
|
||||
}
|
||||
{
|
||||
const v1 = @splat(4, @as(u32, 0xc0ffeeee));
|
||||
const v2: @Vector(4, c_uint) = v1;
|
||||
const v3 = @splat(4, @as(u32, 0xdeadbeef));
|
||||
expectEqual(@splat(4, true), v1 == v2);
|
||||
expectEqual(@splat(4, false), v1 == v3);
|
||||
expectEqual(@splat(4, true), v1 != v3);
|
||||
expectEqual(@splat(4, false), v1 != v2);
|
||||
}
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
@@ -621,9 +621,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("float suffixes",
|
||||
\\#define foo 3.14f
|
||||
\\#define bar 16.e-2l
|
||||
\\#define FOO 0.12345
|
||||
\\#define BAR .12345
|
||||
, &[_][]const u8{
|
||||
"pub const foo = @as(f32, 3.14);",
|
||||
"pub const bar = @as(c_longdouble, 16.e-2);",
|
||||
"pub const FOO = 0.12345;",
|
||||
"pub const BAR = 0.12345;",
|
||||
});
|
||||
|
||||
cases.add("comments",
|
||||
@@ -1358,12 +1362,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("basic macro function",
|
||||
\\extern int c;
|
||||
\\#define BASIC(c) (c*2)
|
||||
\\#define FOO(L,b) (L + b)
|
||||
, &[_][]const u8{
|
||||
\\pub extern var c: c_int;
|
||||
,
|
||||
\\pub inline fn BASIC(c_1: var) @TypeOf(c_1 * 2) {
|
||||
\\ return c_1 * 2;
|
||||
\\}
|
||||
,
|
||||
\\pub inline fn FOO(L: var, b: var) @TypeOf(L + b) {
|
||||
\\ return L + b;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("macro defines string literal with hex",
|
||||
@@ -2529,10 +2538,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
|
||||
cases.add("macro cast",
|
||||
\\#define FOO(bar) baz((void *)(baz))
|
||||
\\#define BAR (void*) a
|
||||
, &[_][]const u8{
|
||||
\\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {
|
||||
\\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));
|
||||
\\}
|
||||
,
|
||||
\\pub const BAR = if (@typeId(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeId(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);
|
||||
});
|
||||
|
||||
cases.add("macro conditional operator",
|
||||
|
||||
Reference in New Issue
Block a user