Merge pull request #133 from birth-software/ditch-allocator-for-arena

Ditch allocator for arena
This commit is contained in:
David 2024-04-10 10:32:26 -06:00 committed by GitHub
commit 097f13957c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 375 additions and 201 deletions

View File

@ -3165,8 +3165,10 @@ fn getTypeAbiAlignment(ty: *Type, unit: *Unit) u32 {
// TODO: is this correct? // TODO: is this correct?
.abi_compatible_error_union => |error_union| { .abi_compatible_error_union => |error_union| {
const t = unit.types.get(error_union.type).getAbiAlignment(unit); const t = unit.types.get(error_union.type).getAbiAlignment(unit);
if (error_union.padding != .null) {
const padding = unit.types.get(error_union.padding).getAbiAlignment(unit); const padding = unit.types.get(error_union.padding).getAbiAlignment(unit);
return @max(t, padding); return @max(t, padding);
} else return t;
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
@ -3226,10 +3228,14 @@ fn getTypeHomogeneousAggregate(ty: *Type, unit: *Unit) ?HomogeneousAggregate {
}; };
} }
const _usize: Type.Index = .u64;
const _ssize: Type.Index = .s64;
pub const Type = union(enum) { pub const Type = union(enum) {
void, void,
noreturn, noreturn,
type, type,
any,
@"struct": Struct.Index, @"struct": Struct.Index,
function: Function.Prototype.Index, function: Function.Prototype.Index,
integer: Type.Integer, integer: Type.Integer,
@ -3238,6 +3244,9 @@ pub const Type = union(enum) {
array: Type.Array, array: Type.Array,
polymorphic: Type.Polymorphic, polymorphic: Type.Polymorphic,
pub const @"usize" = _usize;
pub const @"ssize" = _ssize;
pub const Polymorphic = struct { pub const Polymorphic = struct {
parameters: []const Token.Index, parameters: []const Token.Index,
instantiations: MyHashMap(u32, *Debug.Declaration.Global) = .{}, instantiations: MyHashMap(u32, *Debug.Declaration.Global) = .{},
@ -3323,15 +3332,6 @@ pub const Type = union(enum) {
return getTypeBitSize(ty, unit); return getTypeBitSize(ty, unit);
} }
fn getByteSize(ty: *Type, unit: *Unit) u32 {
_ = unit; // autofix
return switch (ty.*) {
.integer => |integer| std.math.divCeil(u16, integer.bit_count, @bitSizeOf(u8)) catch unreachable,
.pointer => 8,
else => |t| @panic(@tagName(t)),
};
}
pub fn getAbiSize(ty: *Type, unit: *Unit) u32 { pub fn getAbiSize(ty: *Type, unit: *Unit) u32 {
return getTypeAbiSize(ty, unit); return getTypeAbiSize(ty, unit);
} }
@ -3481,6 +3481,7 @@ pub const Type = union(enum) {
noreturn, noreturn,
type, type,
comptime_int, comptime_int,
any,
bool, bool,
u1, u1,
u8, u8,
@ -3491,8 +3492,8 @@ pub const Type = union(enum) {
s16, s16,
s32, s32,
s64, s64,
usize, // usize,
ssize, // ssize,
const bool_type = Type.u1; const bool_type = Type.u1;
@ -3514,6 +3515,7 @@ pub const Type = union(enum) {
.kind = .comptime_int, .kind = .comptime_int,
}, },
}, },
.any = .any,
.u1 = .{ .u1 = .{
.integer = .{ .integer = .{
.bit_count = 1, .bit_count = 1,
@ -3577,20 +3579,20 @@ pub const Type = union(enum) {
.kind = .materialized_int, .kind = .materialized_int,
}, },
}, },
.ssize = .{ // .ssize = .{
.integer = .{ // .integer = .{
.bit_count = 64, // .bit_count = 64,
.signedness = .signed, // .signedness = .signed,
.kind = .materialized_int, // .kind = .materialized_int,
}, // },
}, // },
.usize = .{ // .usize = .{
.integer = .{ // .integer = .{
.bit_count = 64, // .bit_count = 64,
.signedness = .unsigned, // .signedness = .unsigned,
.kind = .materialized_int, // .kind = .materialized_int,
}, // },
}, // },
}); });
}; };
@ -3788,6 +3790,7 @@ pub const Instruction = union(enum) {
pointer_var_to_const, pointer_var_to_const,
pointer_const_to_var, pointer_const_to_var,
pointer_to_nullable, pointer_to_nullable,
pointer_source_type_to_destination_type,
slice_var_to_const, slice_var_to_const,
slice_to_nullable, slice_to_nullable,
slice_to_not_null, slice_to_not_null,
@ -4323,11 +4326,11 @@ pub const Builder = struct {
if (padding_bit_count == 0 and t.* == .integer) { if (padding_bit_count == 0 and t.* == .integer) {
error_union_for_error = abi_type_index; error_union_for_error = abi_type_index;
} else { } else {
const padding_type = try unit.getArrayType(context, .{ const padding_type = if (padding_bit_count != 0) try unit.getArrayType(context, .{
.count = padding_bit_count, .count = padding_bit_count,
.type = .u1, .type = .u1,
.termination = .none, .termination = .none,
}); }) else .null;
const error_union_for_error_struct_index = try unit.structs.append(context.my_allocator, .{ const error_union_for_error_struct_index = try unit.structs.append(context.my_allocator, .{
.kind = .{ .kind = .{
@ -4630,7 +4633,7 @@ pub const Builder = struct {
assert(argument_node_list.len == 1); assert(argument_node_list.len == 1);
const argument_type_index = try builder.resolveType(unit, context, argument_node_list[0], &.{}); const argument_type_index = try builder.resolveType(unit, context, argument_node_list[0], &.{});
const argument_type = unit.types.get(argument_type_index); const argument_type = unit.types.get(argument_type_index);
const argument_size = argument_type.getByteSize(unit); const argument_size = argument_type.getAbiSize(unit);
const integer_value = argument_size; const integer_value = argument_size;
const integer_type = switch (type_expect) { const integer_type = switch (type_expect) {
@ -4641,7 +4644,7 @@ pub const Builder = struct {
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
}, },
.none => .usize, .none => Type.usize,
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
@ -4662,7 +4665,7 @@ pub const Builder = struct {
var instruction_list = try UnpinnedArray(V).initialize_with_capacity(context.my_allocator, @intCast(argument_node_list.len)); var instruction_list = try UnpinnedArray(V).initialize_with_capacity(context.my_allocator, @intCast(argument_node_list.len));
// TODO // TODO
const arg_type_expect = Type.Expect{ const arg_type_expect = Type.Expect{
.type = Type.Index.usize, .type = Type.usize,
}; };
for (argument_node_list) |argument_node_index| { for (argument_node_list) |argument_node_index| {
@ -4682,7 +4685,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = syscall, .runtime = syscall,
}, },
.type = Type.Index.usize, .type = Type.usize,
}; };
} else { } else {
@panic("Syscall argument mismatch"); @panic("Syscall argument mismatch");
@ -4809,7 +4812,7 @@ pub const Builder = struct {
return .pointer_const_to_var; return .pointer_const_to_var;
} }
} else { } else {
unreachable; return .pointer_source_type_to_destination_type;
} }
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
@ -5409,23 +5412,13 @@ pub const Builder = struct {
.integer => |source_integer| switch (source_integer.kind) { .integer => |source_integer| switch (source_integer.kind) {
.materialized_int => { .materialized_int => {
if (destination_integer.signedness == source_integer.signedness) { if (destination_integer.signedness == source_integer.signedness) {
if (destination_integer.bit_count == source_integer.bit_count) { if (destination_integer.bit_count > source_integer.bit_count) {
if (destination_type_index == .usize and source_type_index == .u64) {
return .success;
} else if (destination_type_index == .u64 and source_type_index == .usize) {
return .success;
} else if (destination_type_index == .ssize and source_type_index == .s64) {
return .success;
} else if (destination_type_index == .s64 and source_type_index == .ssize) {
return .success;
} else {
unreachable;
}
} else if (destination_integer.bit_count > source_integer.bit_count) {
return switch (destination_integer.signedness) { return switch (destination_integer.signedness) {
.signed => .sign_extend, .signed => .sign_extend,
.unsigned => .zero_extend, .unsigned => .zero_extend,
}; };
} else if (destination_integer.bit_count == source_integer.bit_count) {
unreachable;
} else { } else {
unreachable; unreachable;
} }
@ -5932,6 +5925,13 @@ pub const Builder = struct {
}; };
return value; return value;
} else { } else {
const has_padding = switch (unit.types.get(error_union.union_for_error).*) {
.@"struct" => |struct_index| switch (unit.structs.get(struct_index).kind) {
.abi_compatible_error_union => |eu| eu.padding != .null,
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
};
const undef = V{ const undef = V{
.value = .{ .value = .{
.@"comptime" = .undefined, .@"comptime" = .undefined,
@ -5956,7 +5956,7 @@ pub const Builder = struct {
}, },
.type = error_union.union_for_error, .type = error_union.union_for_error,
}, },
.index = 2, .index = @as(u32, 1) + @intFromBool(has_padding),
.new_value = .{ .new_value = .{
.value = .{ .value = .{
.@"comptime" = .{ .@"comptime" = .{
@ -6250,8 +6250,13 @@ pub const Builder = struct {
switch (node.id) { switch (node.id) {
.assign, .add_assign, .sub_assign, .div_assign => { .assign, .add_assign, .sub_assign, .div_assign => {
if (unit.getNode(node.left).id == .discard) { if (unit.getNode(node.left).id == .discard) {
const r = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, node.right, .right); _ = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, node.right, .right);
return r; return .{
.value = .{
.@"comptime" = .void,
},
.type = .void,
};
} else { } else {
const left = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, node.left, .left); const left = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, node.left, .left);
const expected_right_type = switch (left.value) { const expected_right_type = switch (left.value) {
@ -6376,7 +6381,7 @@ pub const Builder = struct {
var termination = Type.Termination.none; var termination = Type.Termination.none;
const len_node = unit.getNode(attribute_node_list[0]); const len_node = unit.getNode(attribute_node_list[0]);
const len = switch (len_node.id) { const len = switch (len_node.id) {
else => switch (try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = .usize }, .{}, attribute_node_list[0], null, .right, &.{})) { else => switch (try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = Type.usize }, .{}, attribute_node_list[0], null, .right, &.{})) {
.comptime_int => |ct_int| ct_int.value, .comptime_int => |ct_int| ct_int.value,
.constant_int => |constant_int| constant_int.value, .constant_int => |constant_int| constant_int.value,
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
@ -6413,14 +6418,14 @@ pub const Builder = struct {
const result: Type.Index = switch (node.id) { const result: Type.Index = switch (node.id) {
.keyword_noreturn => .noreturn, .keyword_noreturn => .noreturn,
.usize_type => .usize, .usize_type => Type.usize,
.void_type => .void, .void_type => .void,
.identifier, .field_access => { .identifier, .field_access => {
const resolved_type_value = try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = .type }, .{}, node_index, null, .right, new_parameters); const resolved_type_value = try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = .type }, .{}, node_index, null, .right, new_parameters);
return resolved_type_value.type; return resolved_type_value.type;
}, },
.bool_type => .bool, .bool_type => .bool,
.ssize_type => .ssize, .ssize_type => Type.ssize,
.signed_integer_type, .signed_integer_type,
.unsigned_integer_type, .unsigned_integer_type,
=> b: { => b: {
@ -6445,6 +6450,7 @@ pub const Builder = struct {
.usize_type, .usize_type,
.pointer_type, .pointer_type,
.self, .self,
.any,
=> { => {
if (element_type_index != .null) { if (element_type_index != .null) {
unreachable; unreachable;
@ -6638,6 +6644,7 @@ pub const Builder = struct {
return type_index; return type_index;
} }
}, },
.any => .any,
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
@ -7121,12 +7128,10 @@ pub const Builder = struct {
.u16, .u16,
.u32, .u32,
.u64, .u64,
.usize,
.s8, .s8,
.s16, .s16,
.s32, .s32,
.s64, .s64,
.ssize,
.bool, .bool,
=> result[current_index] = .integer, => result[current_index] = .integer,
else => switch (integer.kind) { else => switch (integer.kind) {
@ -7310,7 +7315,7 @@ pub const Builder = struct {
switch (ty.*) { switch (ty.*) {
.pointer => return if (offset == 0) type_index else unreachable, .pointer => return if (offset == 0) type_index else unreachable,
.integer => |integer| switch (type_index) { .integer => |integer| switch (type_index) {
.u64, .s64, .usize, .ssize => return type_index, .u64, .s64 => return type_index,
.bool, .u8, .u16, .u32, .s8, .s16, .s32 => { .bool, .u8, .u16, .u32, .s8, .s16, .s32 => {
if (offset != 0) unreachable; if (offset != 0) unreachable;
const start = source_offset + ty.getAbiSize(unit); const start = source_offset + ty.getAbiSize(unit);
@ -8523,7 +8528,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
.name = try unit.processIdentifier(context, "direct_pair"), .name = try unit.processIdentifier(context, "direct_pair"),
}, },
@ -8913,7 +8918,7 @@ pub const Builder = struct {
.type = type_index, .type = type_index,
}; };
}, },
.unsigned_integer_type => return .{ .unsigned_integer_type, .signed_integer_type => return .{
.type = try builder.resolveType(unit, context, node_index, new_parameters), .type = try builder.resolveType(unit, context, node_index, new_parameters),
}, },
.@"switch" => return try builder.resolveComptimeSwitch(unit, context, type_expect, global_attributes, node_index, maybe_global), .@"switch" => return try builder.resolveComptimeSwitch(unit, context, type_expect, global_attributes, node_index, maybe_global),
@ -8926,13 +8931,7 @@ pub const Builder = struct {
else => unreachable, else => unreachable,
}; };
}, },
.signed_integer_type => { .add, .mul => {
const result = try builder.resolveIntegerType(unit, context, node_index);
return .{
.type = result,
};
},
.add => {
const left = try builder.resolveComptimeValue(unit, context, Type.Expect.none, .{}, node.left, null, .right, &.{}); const left = try builder.resolveComptimeValue(unit, context, Type.Expect.none, .{}, node.left, null, .right, &.{});
const left_type = left.getType(unit); const left_type = left.getType(unit);
const right = try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = left_type }, .{}, node.right, null, .right, &.{}); const right = try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = left_type }, .{}, node.right, null, .right, &.{});
@ -8944,7 +8943,11 @@ pub const Builder = struct {
.comptime_int => |right_ct_int| { .comptime_int => |right_ct_int| {
assert(right_ct_int.signedness == .unsigned); assert(right_ct_int.signedness == .unsigned);
const right_value = right_ct_int.value; const right_value = right_ct_int.value;
const result = left_value + right_value; const result = switch (node.id) {
.add => left_value + right_value,
.mul => left_value * right_value,
else => unreachable,
};
return .{ return .{
.comptime_int = .{ .comptime_int = .{
.value = result, .value = result,
@ -9139,7 +9142,7 @@ pub const Builder = struct {
.pointer_dereference => block: { .pointer_dereference => block: {
// TODO: // TODO:
const pointer_type_expect = switch (type_expect) { const pointer_type_expect = switch (type_expect) {
.none => unreachable, //type_expect, .none => type_expect,
.type => |type_index| b: { .type => |type_index| b: {
const pointer_type = try unit.getPointerType(context, .{ const pointer_type = try unit.getPointerType(context, .{
.type = type_index, .type = type_index,
@ -9159,8 +9162,18 @@ pub const Builder = struct {
// TODO: is this right? .right // TODO: is this right? .right
const pointer_value = try builder.resolveRuntimeValue(unit, context, pointer_type_expect, node.left, .right); const pointer_value = try builder.resolveRuntimeValue(unit, context, pointer_type_expect, node.left, .right);
break :block switch (side) {
.left => pointer_value,
.right => right: {
const load_type = switch (type_expect) { const load_type = switch (type_expect) {
.none => unreachable, .none => b: {
const pointer_type = unit.types.get(pointer_value.type);
const pointer_element_type = pointer_type.pointer.type;
switch (unit.types.get(pointer_element_type).*) {
else => |t| @panic(@tagName(t)),
}
break :b pointer_element_type;
},
.type => |type_index| type_index, .type => |type_index| type_index,
else => unreachable, else => unreachable,
}; };
@ -9173,13 +9186,15 @@ pub const Builder = struct {
}); });
try builder.appendInstruction(unit, context, load); try builder.appendInstruction(unit, context, load);
break :block .{ break :right .{
.value = .{ .value = .{
.runtime = load, .runtime = load,
}, },
.type = load_type, .type = load_type,
}; };
}, },
};
},
.compare_equal, .compare_equal,
.compare_not_equal, .compare_not_equal,
.compare_greater, .compare_greater,
@ -9685,7 +9700,7 @@ pub const Builder = struct {
const range_node = unit.getNode(node.right); const range_node = unit.getNode(node.right);
assert(range_node.id == .range); assert(range_node.id == .range);
const range_start: V = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .usize }, range_node.left, .right); const range_start: V = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = Type.usize }, range_node.left, .right);
const range_end: V = switch (range_node.right) { const range_end: V = switch (range_node.right) {
.null => switch (unit.types.get(expression_to_slice.type).*) { .null => switch (unit.types.get(expression_to_slice.type).*) {
.slice => b: { .slice => b: {
@ -9701,7 +9716,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = extract_value, .runtime = extract_value,
}, },
.type = .usize, .type = Type.usize,
}; };
}, },
.pointer => |pointer| switch (pointer.many) { .pointer => |pointer| switch (pointer.many) {
@ -9715,7 +9730,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
.slice => |slice| b: { .slice => |slice| b: {
_ = slice; // autofix _ = slice; // autofix
@ -9747,14 +9762,14 @@ pub const Builder = struct {
.runtime = gep, .runtime = gep,
}, },
.type = try unit.getPointerType(context, .{ .type = try unit.getPointerType(context, .{
.type = .usize, .type = Type.usize,
.termination = .none, .termination = .none,
.many = false, .many = false,
.nullable = false, .nullable = false,
.mutability = .@"const", .mutability = .@"const",
}), }),
}, },
.type = .usize, .type = Type.usize,
}, },
}); });
try builder.appendInstruction(unit, context, load); try builder.appendInstruction(unit, context, load);
@ -9763,7 +9778,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = load, .runtime = load,
}, },
.type = .usize, .type = Type.usize,
}; };
}, },
.pointer => |child_pointer| b: { .pointer => |child_pointer| b: {
@ -9778,7 +9793,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}; };
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
@ -9790,7 +9805,7 @@ pub const Builder = struct {
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
else => try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .usize }, range_node.right, .right), else => try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = Type.usize }, range_node.right, .right),
}; };
const len_expression: V = b: { const len_expression: V = b: {
@ -9812,7 +9827,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}; };
} else { } else {
const range_compute = try unit.instructions.append(context.my_allocator, .{ const range_compute = try unit.instructions.append(context.my_allocator, .{
@ -9830,7 +9845,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = range_compute, .runtime = range_compute,
}, },
.type = .usize, .type = Type.usize,
}; };
} }
}; };
@ -10381,7 +10396,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
}, },
}); });
@ -10527,7 +10542,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
}, },
}); });
@ -10584,7 +10599,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
}, },
}); });
@ -10649,7 +10664,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
}, },
}); });
@ -10749,7 +10764,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
else => original_index_value, else => original_index_value,
}; };
@ -11229,8 +11244,21 @@ pub const Builder = struct {
.error_union => |return_error_union| { .error_union => |return_error_union| {
switch (try builder.typecheck(unit, context, return_error_union.@"error", error_union.@"error")) { switch (try builder.typecheck(unit, context, return_error_union.@"error", error_union.@"error")) {
.success => { .success => {
const error_value = if (error_union.union_for_error == error_union.abi) { const error_value = if (error_union.union_for_error == error_union.abi) blk: {
unreachable; const extract_value = try unit.instructions.append(context.my_allocator, .{
.extract_value = .{
.expression = value,
.index = 0,
},
});
try builder.appendInstruction(unit, context, extract_value);
break :blk V{
.type = error_union.abi,
.value = .{
.runtime = extract_value,
},
};
} else err: { } else err: {
const try_alloca = try builder.createStackVariable(unit, context, value.type, null); const try_alloca = try builder.createStackVariable(unit, context, value.type, null);
@ -11342,6 +11370,14 @@ pub const Builder = struct {
.type = return_type_index, .type = return_type_index,
}; };
} else { } else {
const has_padding = switch (unit.types.get(error_union.union_for_error).*) {
.@"struct" => |si| switch (unit.structs.get(si).kind) {
.abi_compatible_error_union => |eu| eu.padding != .null,
.raw_error_union => false,
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
};
const v = V{ const v = V{
.value = .{ .value = .{
.@"comptime" = .undefined, .@"comptime" = .undefined,
@ -11366,7 +11402,7 @@ pub const Builder = struct {
}, },
.type = error_union.union_for_error, .type = error_union.union_for_error,
}, },
.index = 2, .index = @as(u32, 1) + @intFromBool(has_padding),
.new_value = .{ .new_value = .{
.value = .{ .value = .{
.@"comptime" = .{ .@"comptime" = .{
@ -11623,6 +11659,10 @@ pub const Builder = struct {
.type = field.type, .type = field.type,
}); });
} else { } else {
const identifier = unit.getIdentifier(field.name);
try write(.panic, "Missing field: ");
try write(.panic, identifier);
try write(.panic, "\n");
@panic("Missing field"); @panic("Missing field");
} }
} }
@ -11957,6 +11997,8 @@ pub const Builder = struct {
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
} }
} else { } else {
try write(.panic, "Right identifier in field access like call expression: ");
try write(.panic, right_identifier);
@panic("Right identifier in field access like call expression"); @panic("Right identifier in field access like call expression");
//std.debug.panic("Right identifier in field-access-like call expression not found: '{s}'", .{right_identifier}); //std.debug.panic("Right identifier in field-access-like call expression not found: '{s}'", .{right_identifier});
} }
@ -12372,7 +12414,10 @@ pub const Builder = struct {
const argument_value = try builder.resolveRuntimeValue(unit, context, arg_type_expect, argument_node_index, .right); const argument_value = try builder.resolveRuntimeValue(unit, context, arg_type_expect, argument_node_index, .right);
switch (argument_abi.kind) { switch (argument_abi.kind) {
.direct => argument_list.append_with_capacity(argument_value), .direct => {
assert(argument_value.type == argument_type_index);
argument_list.append_with_capacity(argument_value);
},
.direct_coerce => |coerced_type_index| if (coerced_type_index == argument_value.type) argument_list.append_with_capacity(argument_value) else { .direct_coerce => |coerced_type_index| if (coerced_type_index == argument_value.type) argument_list.append_with_capacity(argument_value) else {
const stack = try builder.createStackVariable(unit, context, argument_value.type, null); const stack = try builder.createStackVariable(unit, context, argument_value.type, null);
@ -12945,7 +12990,35 @@ pub const Builder = struct {
}; };
} else typecheck_enum_result.else_switch_case_group_index orelse unreachable; } else typecheck_enum_result.else_switch_case_group_index orelse unreachable;
const true_switch_case_node = unit.getNode(case_nodes[group_index]); const true_switch_case_node = unit.getNode(case_nodes[group_index]);
_ = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, true_switch_case_node.right, .right); const value = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, true_switch_case_node.right, .right);
switch (value.type) {
.void, .noreturn => {},
else => @panic("Unexpected type"),
}
},
.bool => |boolean| {
assert(case_nodes.len == 2);
for (case_nodes) |case_node_index| {
const case_node = unit.getNode(case_node_index);
assert(case_node.left != .null);
assert(case_node.right != .null);
const boolean_value = try builder.resolveComptimeValue(unit, context, Type.Expect{ .type = .bool }, .{}, case_node.left, null, .right, &.{});
switch (boolean_value) {
.bool => |case_boolean| {
if (case_boolean == boolean) {
const v = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, case_node.right, .right);
switch (v.type) {
.void, .noreturn => break,
else => @panic("Unexpected type"),
}
}
},
else => |t| @panic(@tagName(t)),
}
} else {
unreachable;
}
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
@ -13038,9 +13111,9 @@ pub const Builder = struct {
.range => blk: { .range => blk: {
assert(last_element_node.left != .null); assert(last_element_node.left != .null);
const range_start = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .usize }, last_element_node.left, .right); const range_start = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = Type.usize }, last_element_node.left, .right);
const emit = true; const emit = true;
const stack_slot = try builder.emitLocalVariableDeclaration(unit, context, last_element_payload.token, .@"var", .usize, range_start, emit, null); const stack_slot = try builder.emitLocalVariableDeclaration(unit, context, last_element_payload.token, .@"var", Type.usize, range_start, emit, null);
// This is put up here so that the length is constant throughout the loop and we dont have to load the variable unnecessarily // This is put up here so that the length is constant throughout the loop and we dont have to load the variable unnecessarily
const range_end = switch (last_element_node.right) { const range_end = switch (last_element_node.right) {
.null => switch (unit.types.get(slices.pointer[0].type).*) { .null => switch (unit.types.get(slices.pointer[0].type).*) {
@ -13057,12 +13130,12 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = len_extract_instruction, .runtime = len_extract_instruction,
}, },
.type = .usize, .type = Type.usize,
}; };
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
else => try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .usize }, last_element_node.right, .right), else => try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = Type.usize }, last_element_node.right, .right),
}; };
break :blk .{ break :blk .{
@ -13080,7 +13153,7 @@ pub const Builder = struct {
const name = try join_name(context, "__anon_i_", unit.anon_i, 10); const name = try join_name(context, "__anon_i_", unit.anon_i, 10);
unit.anon_i += 1; unit.anon_i += 1;
const emit = true; const emit = true;
const stack_slot = try builder.emitLocalVariableDeclaration(unit, context, last_element_payload.token, .@"var", .usize, .{ const stack_slot = try builder.emitLocalVariableDeclaration(unit, context, last_element_payload.token, .@"var", Type.usize, .{
.value = .{ .value = .{
.@"comptime" = .{ .@"comptime" = .{
.constant_int = .{ .constant_int = .{
@ -13088,7 +13161,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, emit, name); }, emit, name);
const len_extract_value = try unit.instructions.append(context.my_allocator, .{ const len_extract_value = try unit.instructions.append(context.my_allocator, .{
@ -13105,7 +13178,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = len_extract_value, .runtime = len_extract_value,
}, },
.type = .usize, .type = Type.usize,
}, },
}; };
}, },
@ -13119,7 +13192,7 @@ pub const Builder = struct {
builder.current_basic_block = loop_header; builder.current_basic_block = loop_header;
const pointer_to_usize = try unit.getPointerType(context, .{ const pointer_to_usize = try unit.getPointerType(context, .{
.type = .usize, .type = Type.usize,
.mutability = .@"const", .mutability = .@"const",
.nullable = false, .nullable = false,
.many = false, .many = false,
@ -13134,7 +13207,7 @@ pub const Builder = struct {
}, },
.type = pointer_to_usize, .type = pointer_to_usize,
}, },
.type = .usize, .type = Type.usize,
}, },
}); });
@ -13146,10 +13219,10 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = load, .runtime = load,
}, },
.type = .usize, .type = Type.usize,
}, },
.right = loop_counter.end, .right = loop_counter.end,
.type = .usize, .type = Type.usize,
.id = .unsigned_less, .id = .unsigned_less,
}, },
}); });
@ -13175,7 +13248,7 @@ pub const Builder = struct {
}, },
.type = pointer_to_usize, .type = pointer_to_usize,
}, },
.type = .usize, .type = Type.usize,
}, },
}); });
try builder.appendInstruction(unit, context, load_i); try builder.appendInstruction(unit, context, load_i);
@ -13254,7 +13327,7 @@ pub const Builder = struct {
}, },
.type = pointer_to_usize, .type = pointer_to_usize,
}, },
.type = .usize, .type = Type.usize,
}, },
}); });
@ -13266,7 +13339,7 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = load_iterator, .runtime = load_iterator,
}, },
.type = .usize, .type = Type.usize,
}, },
.right = .{ .right = .{
.value = .{ .value = .{
@ -13276,7 +13349,7 @@ pub const Builder = struct {
}, },
}, },
}, },
.type = .usize, .type = Type.usize,
}, },
.id = .add, .id = .add,
.signedness = .unsigned, .signedness = .unsigned,
@ -13291,13 +13364,13 @@ pub const Builder = struct {
.value = .{ .value = .{
.runtime = loop_counter.stack_slot, .runtime = loop_counter.stack_slot,
}, },
.type = .usize, .type = Type.usize,
}, },
.source = .{ .source = .{
.value = .{ .value = .{
.runtime = increment, .runtime = increment,
}, },
.type = .usize, .type = Type.usize,
}, },
}, },
}); });
@ -14076,7 +14149,7 @@ pub const Builder = struct {
} else unreachable; } else unreachable;
const field_type = switch (slice_field) { const field_type = switch (slice_field) {
.pointer => slice.child_pointer_type, .pointer => slice.child_pointer_type,
.length => Type.Index.usize, .length => Type.usize,
}; };
const field_index = @intFromEnum(slice_field); const field_index = @intFromEnum(slice_field);
@ -14108,7 +14181,7 @@ pub const Builder = struct {
.runtime = gep, .runtime = gep,
}, },
.type = try unit.getPointerType(context, .{ .type = try unit.getPointerType(context, .{
.type = .usize, .type = Type.usize,
.many = false, .many = false,
.nullable = false, .nullable = false,
.termination = .none, .termination = .none,
@ -14535,6 +14608,13 @@ pub const Builder = struct {
.type = ti, .type = ti,
}; };
} else { } else {
const has_padding = switch (unit.types.get(error_union.union_for_error).*) {
.@"struct" => |si| switch (unit.structs.get(si).kind) {
.abi_compatible_error_union => |eu| eu.padding != .null,
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
};
const v = V{ const v = V{
.value = .{ .value = .{
.@"comptime" = .undefined, .@"comptime" = .undefined,
@ -14559,7 +14639,7 @@ pub const Builder = struct {
}, },
.type = error_union.union_for_error, .type = error_union.union_for_error,
}, },
.index = 2, .index = @as(u32, 1) + @intFromBool(has_padding),
.new_value = .{ .new_value = .{
.value = .{ .value = .{
.@"comptime" = .{ .@"comptime" = .{
@ -15609,6 +15689,7 @@ pub const Unit = struct {
if (unit.arrays.get(array)) |array_type| { if (unit.arrays.get(array)) |array_type| {
return array_type; return array_type;
} else { } else {
assert(array.count != 0);
const array_type = try unit.types.append(context.my_allocator, .{ const array_type = try unit.types.append(context.my_allocator, .{
.array = array, .array = array,
}); });
@ -16052,6 +16133,7 @@ pub const FixedKeyword = enum {
@"or", @"or",
bitfield, bitfield,
Self, Self,
any,
}; };
pub const Descriptor = struct { pub const Descriptor = struct {
@ -16264,6 +16346,7 @@ pub const Token = struct {
fixed_keyword_or, fixed_keyword_or,
fixed_keyword_bitfield, fixed_keyword_bitfield,
fixed_keyword_Self, fixed_keyword_Self,
fixed_keyword_any,
unused1, unused1,
unused2, unused2,
unused3, unused3,

View File

@ -1254,7 +1254,7 @@ pub const LLVM = struct {
}, },
.slice => |slice| blk: { .slice => |slice| blk: {
const llvm_pointer_type = try llvm.getType(unit, context, slice.child_pointer_type); const llvm_pointer_type = try llvm.getType(unit, context, slice.child_pointer_type);
const llvm_usize_type = try llvm.getType(unit, context, .usize); const llvm_usize_type = try llvm.getType(unit, context, Compilation.Type.usize);
const slice_types = [_]*Type{ llvm_pointer_type, llvm_usize_type }; const slice_types = [_]*Type{ llvm_pointer_type, llvm_usize_type };
const is_packed = false; const is_packed = false;
const struct_type = llvm.context.getStructType(&slice_types, slice_types.len, is_packed) orelse return Type.Error.@"struct"; const struct_type = llvm.context.getStructType(&slice_types, slice_types.len, is_packed) orelse return Type.Error.@"struct";
@ -1272,11 +1272,19 @@ pub const LLVM = struct {
}, },
.abi_compatible_error_union => |error_union| blk: { .abi_compatible_error_union => |error_union| blk: {
const error_union_type = try llvm.getType(unit, context, error_union.type); const error_union_type = try llvm.getType(unit, context, error_union.type);
const padding_type = try llvm.getType(unit, context, error_union.padding);
const boolean_type = try llvm.getType(unit, context, .bool); const boolean_type = try llvm.getType(unit, context, .bool);
const types = [3]*LLVM.Type{ error_union_type, padding_type, boolean_type }; var three_types: [3]*LLVM.Type = undefined;
var two_types: [2]*LLVM.Type = undefined;
const types: []const *LLVM.Type = if (error_union.padding == .null) b: {
two_types = .{ error_union_type, boolean_type };
break :b &two_types;
} else b: {
const padding_type = try llvm.getType(unit, context, error_union.padding);
three_types = .{ error_union_type, padding_type, boolean_type };
break :b &three_types;
};
const is_packed = false; const is_packed = false;
const struct_type = llvm.context.getStructType(&types, types.len, is_packed) orelse return Type.Error.@"struct"; const struct_type = llvm.context.getStructType(types.ptr, types.len, is_packed) orelse return Type.Error.@"struct";
break :blk struct_type.toType(); break :blk struct_type.toType();
}, },
.@"struct" => |*sema_struct_type| blk: { .@"struct" => |*sema_struct_type| blk: {
@ -1406,6 +1414,7 @@ pub const LLVM = struct {
}, },
// TODO // TODO
.function => "fn_type", .function => "fn_type",
.any => "any",
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
@ -1669,15 +1678,49 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
.pointer => |pointer| b: { .pointer => |pointer| b: {
if (pointer.type == .any) {
const flags = LLVM.DebugInfo.Node.Flags{
.visibility = .none,
.forward_declaration = false,
.apple_block = false,
.block_by_ref_struct = false,
.virtual = false,
.artificial = false,
.explicit = false,
.prototyped = false,
.objective_c_class_complete = false,
.object_pointer = false,
.vector = false,
.static_member = false,
.lvalue_reference = false,
.rvalue_reference = false,
.reserved = false,
.inheritance = .none,
.introduced_virtual = false,
.bit_field = false,
.no_return = false,
.type_pass_by_value = false,
.type_pass_by_reference = false,
.enum_class = false,
.thunk = false,
.non_trivial = false,
.big_endian = false,
.little_endian = false,
.all_calls_described = false,
};
const pointer_type = llvm.debug_info_builder.createBasicType(name.ptr, name.len, 64, .address, flags) orelse unreachable;
break :b pointer_type;
} else {
const element_type = try llvm.getDebugType(unit, context, pointer.type); const element_type = try llvm.getDebugType(unit, context, pointer.type);
const pointer_width = @bitSizeOf(usize); const pointer_width = @bitSizeOf(usize);
const alignment = 3; const alignment = 3;
const pointer_type = llvm.debug_info_builder.createPointerType(element_type, pointer_width, alignment, name.ptr, name.len) orelse unreachable; const pointer_type = llvm.debug_info_builder.createPointerType(element_type, pointer_width, alignment, name.ptr, name.len) orelse unreachable;
break :b pointer_type.toType(); break :b pointer_type.toType();
}
}, },
.slice => |slice| b: { .slice => |slice| b: {
const pointer_type = try llvm.getDebugType(unit, context, slice.child_pointer_type); const pointer_type = try llvm.getDebugType(unit, context, slice.child_pointer_type);
const len_type = try llvm.getDebugType(unit, context, .usize); const len_type = try llvm.getDebugType(unit, context, Compilation.Type.usize);
const scope = null; const scope = null;
const file = null; const file = null;
const line = 1; const line = 1;
@ -1733,6 +1776,7 @@ pub const LLVM = struct {
const byte_size = 1; // array.count * unit.types.get(array.element_type).getSize(); const byte_size = 1; // array.count * unit.types.get(array.element_type).getSize();
const bit_size = byte_size * 8; const bit_size = byte_size * 8;
const element_type = try llvm.getDebugType(unit, context, array.type); const element_type = try llvm.getDebugType(unit, context, array.type);
assert(array.count != 0);
const array_type = llvm.debug_info_builder.createArrayType(bit_size, 1, element_type, array.count) orelse unreachable; const array_type = llvm.debug_info_builder.createArrayType(bit_size, 1, element_type, array.count) orelse unreachable;
break :b array_type.toType(); break :b array_type.toType();
}, },
@ -2630,6 +2674,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.pointer_to_nullable, .pointer_to_nullable,
.pointer_const_to_var, .pointer_const_to_var,
.pointer_to_array_to_pointer_to_many, .pointer_to_array_to_pointer_to_many,
.pointer_source_type_to_destination_type,
=> { => {
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, value); try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, value);
}, },
@ -2789,7 +2834,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
syscall_argument_type.* = syscall_argument.*.getType(); syscall_argument_type.* = syscall_argument.*.getType();
} }
const return_type = try llvm.getType(unit, context, Compilation.Type.Index.usize); const return_type = try llvm.getType(unit, context, Compilation.Type.usize);
const is_var_args = false; const is_var_args = false;
const function_type = LLVM.Context.getFunctionType(return_type, syscall_argument_types.ptr, syscall_argument_types.len, is_var_args) orelse unreachable; const function_type = LLVM.Context.getFunctionType(return_type, syscall_argument_types.ptr, syscall_argument_types.len, is_var_args) orelse unreachable;
var constraints = UnpinnedArray(u8){}; var constraints = UnpinnedArray(u8){};

View File

@ -198,6 +198,7 @@ pub const Node = struct {
bitfield_type, bitfield_type,
comptime_expression, comptime_expression,
self, self,
any,
}; };
}; };
@ -1874,6 +1875,15 @@ const Analyzer = struct {
const token = analyzer.peekToken(); const token = analyzer.peekToken();
return try switch (token) { return try switch (token) {
.fixed_keyword_any => try analyzer.addNode(.{
.id = .any,
.token = b: {
analyzer.consumeToken();
break :b token_i;
},
.left = .null,
.right = .null,
}),
.fixed_keyword_Self => try analyzer.addNode(.{ .fixed_keyword_Self => try analyzer.addNode(.{
.id = .self, .id = .self,
.token = b: { .token = b: {
@ -2051,6 +2061,7 @@ const Analyzer = struct {
.right = backing_type, .right = backing_type,
}); });
}, },
.operator_ampersand => try analyzer.pointerOrArrayTypeExpression(.single_pointer_type),
else => |t| switch (t) { else => |t| switch (t) {
.identifier => @panic(analyzer.bytes(token_i)), .identifier => @panic(analyzer.bytes(token_i)),
else => @panic(@tagName(t)), else => @panic(@tagName(t)),

View File

@ -441,8 +441,59 @@ const waitpid = fn(pid: Process.Id, flags: u32) WaitPidError!u32 {
} }
const reserve = fn (size: u64) *!&any {
switch (current) {
.linux, .macos => {
const syscall_result = system.mmap(null, size, .{
.read = false,
.write = false,
.execute = false,
}, .{
.anonymous = true,
.private = true,
.shared = false,
.fixed = false,
}, -1, 0);
switch (link_libc) {
true => {
if (syscall_result != system.MAP_FAILED) {
const result: &any = #cast(syscall_result);
return result;
} else {
unreachable;
}
},
false => {
const result = unwrap_syscall(syscall_result) catch |err| switch (err) {
else => unreachable,
};
const pointer: &any = #cast(result);
return pointer;
},
}
},
else => #error("OS not supported"),
}
}
const commit = fn (reserved_memory: &any, size: u64) *!void {
switch (current) {
.linux, .macos => {
const syscall_result = system.mprotect(reserved_memory, size, .{
.read = true,
.write = true,
.execute = false,
});
},
else => #error("OS not supported"),
}
}
const MemFdCreateError = error{ const MemFdCreateError = error{
}; };
const memfd_create = fn(name: [&:0]const u8, flags: u32) MemFdCreateError!FileDescriptor{ const memfd_create = fn(name: [&:0]const u8, flags: u32) MemFdCreateError!FileDescriptor{
switch (current) { switch (current) {
.linux => { .linux => {

View File

@ -872,6 +872,12 @@ const mmap = fn(address: ?[&]u8, length: usize, protection_flags: ProtectionFlag
return result; return result;
} }
const mprotect = fn(address: &any, length: usize, protection_flags: ProtectionFlags) usize {
const flat_protection_flags: u32 = #cast(protection_flags);
const result = #syscall(#cast(Syscall.mprotect), #cast(address), length, flat_protection_flags);
return result;
}
const munmap = fn(bytes: []const u8) usize { const munmap = fn(bytes: []const u8) usize {
const result = #syscall(#cast(Syscall.munmap), #cast(bytes.pointer), bytes.length); const result = #syscall(#cast(Syscall.munmap), #cast(bytes.pointer), bytes.length);
return result; return result;

View File

@ -70,74 +70,55 @@ const print_u8 = fn(n: u8) void {
print_usize(n); print_usize(n);
} }
const Allocator = struct { const kilobytes = fn (n: u64) u64 {
handler: &const fn(allocator: &Allocator, old_ptr: ?[&]const u8, old_size: usize, new_size: usize, alignment: u16) Allocator.Error![&]u8, return n * 1024;
}
const Error = error{ const megabytes = fn (n: u64) u64 {
out_of_memory, return n * 1024 * 1024;
free_failed, }
const gigabytes = fn (n: u64) u64 {
return n * 1024 * 1024 * 1024;
}
const terabytes = fn (n: u64) u64 {
return n * 1024 * 1024 * 1024 * 1024;
}
const Arena = struct{
position: u64,
commit_position: u64,
alignment: u64,
size: u64,
const Temporary = struct{
arena: &Arena,
position: u64,
}; };
const allocate = fn (allocator: &Allocator, size: usize, alignment: u16) Allocator.Error![]u8 { const commit_granularity = 2 * 1024 * 1024;
const pointer = try allocator.handler(allocator, old_ptr = null, old_size = 0, new_size = size, alignment);
return pointer[0..size];
}
const free = fn (allocator: &Allocator, bytes: []const u8) Allocator.Error!void { const allocate = fn (requested_size: u64) *!&Arena {
_ = try allocator.handler(allocator, old_ptr = bytes.pointer, old_size = bytes.length, new_size = 0, alignment = 0); var size = requested_size;
} const size_roundup_granularity = megabytes(64);
size += size_roundup_granularity - 1;
size -= size % size_roundup_granularity;
const initial_commit_size = commit_granularity;
assert(initial_commit_size >= #size(Arena));
const duplicate_bytes = fn (allocator: &Allocator, bytes: []const u8) Allocator.Error![]u8 { const reserved_memory = try os.reserve(size);
const result = try allocator.allocate(size = bytes.length, alignment = 0); try os.commit(reserved_memory, initial_commit_size);
copy_bytes(destination = result, source = bytes);
return result; const arena: &Arena = #cast(reserved_memory);
} arena.@ = .{
.position = #size(Arena),
.commit_position = initial_commit_size,
.alignment = 8,
.size = size,
}; };
const PageAllocator = struct{ return arena;
allocator: Allocator = .{
.handler = handler.&,
},
const allocate = fn (a: &PageAllocator, size: usize, alignment: u16) Allocator.Error![]u8 {
const allocation_result = try a.allocator.allocate(size, alignment);
return allocation_result;
}
const free = fn (a: &PageAllocator, bytes: []const u8) Allocator.Error!void {
try a.allocator.free(bytes);
}
const handler = fn (allocator: &Allocator, maybe_old_ptr: ?[&]const u8, old_size: usize, new_size: usize, alignment: u16) Allocator.Error![&]u8{
var maybe_new_ptr: [&]u8 = undefined;
if (new_size > 0) {
const general_protection_flags = os.ProtectionFlags{
.read = true,
.write = true,
.execute = false,
};
const general_map_flags = os.MapFlags{
.reserve = true,
.commit = true,
};
maybe_new_ptr = os.allocate_virtual_memory(address = null, length = new_size, general_protection_flags, general_map_flags) catch return Allocator.Error.out_of_memory;
}
if (maybe_old_ptr) |old_ptr| {
if (new_size > 0) {
unreachable;
} else {
os.free_virtual_memory(old_ptr[0..old_size]) catch return Allocator.Error.free_failed;
return undefined;
}
} else {
return maybe_new_ptr;
}
}
const get_allocator = fn(page_allocator: &PageAllocator) &Allocator {
return page_allocator.allocator.&;
} }
}; };

View File

@ -1,9 +1,6 @@
const std = #import("std"); const std = #import("std");
const Arena = std.Arena;
const main = fn() *!void { const main = fn() *!void {
const size = 0x1000; var arena = try Arena.allocate(2*1024*1024);
const result = try std.page_allocator.allocate(size, alignment = 12);
result[0] = 0;
try std.page_allocator.free(result);
} }