Bitcast string

This commit is contained in:
David Gonzalez Martin 2024-04-23 09:45:47 -06:00
parent 887bcc676c
commit c56e80d30c
3 changed files with 108 additions and 24 deletions

View File

@ -3863,6 +3863,7 @@ pub const Instruction = union(enum) {
error_union_type_int_to_pointer, error_union_type_int_to_pointer,
error_union_type_upcast, error_union_type_upcast,
error_union_type_downcast, error_union_type_downcast,
array_bitcast_to_integer,
}; };
}; };
@ -4708,6 +4709,36 @@ pub const Builder = struct {
.type => |type_index| { .type => |type_index| {
const cast_id = try builder.resolveCast(unit, context, type_index, v); const cast_id = try builder.resolveCast(unit, context, type_index, v);
switch (cast_id) { switch (cast_id) {
.array_bitcast_to_integer => switch (v.value) {
.@"comptime" => |ct| switch (ct) {
.constant_array => |constant_array_index| {
const constant_array = unit.constant_arrays.get(constant_array_index);
const array_type = unit.types.get(constant_array.type).array;
switch (array_type.type) {
.u8 => {
var value: u64 = 0;
_ = &value;
for (constant_array.values, 0..) |array_value, i| {
value |= array_value.constant_int.value << @as(u6, @intCast(i * 8));
}
return V{
.value = .{
.@"comptime" = .{
.constant_int = .{
.value = value,
},
},
},
.type = type_index,
};
},
else => unreachable,
}
},
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
},
else => { else => {
const instruction = try unit.instructions.append(context.my_allocator, .{ const instruction = try unit.instructions.append(context.my_allocator, .{
.cast = .{ .cast = .{
@ -5359,6 +5390,18 @@ pub const Builder = struct {
return .pointer_to_int; return .pointer_to_int;
}, },
.array => |source_array| {
const array_size = source_array.count * unit.types.get(source_array.type).getAbiSize(unit);
if (destination_integer.bit_count % 8 != 0) {
unreachable;
}
const destination_byte_count = @divExact(destination_integer.bit_count, 8);
if (destination_byte_count == array_size) {
return .array_bitcast_to_integer;
} else {
unreachable;
}
},
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
.@"error" => |_| switch (source_type.*) { .@"error" => |_| switch (source_type.*) {
@ -9859,7 +9902,39 @@ pub const Builder = struct {
else => unreachable, else => unreachable,
}; };
// TODO: is this right? .right const left_node = unit.getNode(node.left);
switch (left_node.id) {
.string_literal => {
const string_literal = try unit.fixupStringLiteral(context, left_node.token);
var values = try UnpinnedArray(V.Comptime).initialize_with_capacity(context.my_allocator, @intCast(string_literal.len));
for (string_literal) |b| {
values.append_with_capacity(V.Comptime{
.constant_int = .{
.value = b,
},
});
}
const array_type = try unit.getArrayType(context, .{
.count = string_literal.len,
.type = .u8,
.termination = .none,
});
return V{
.value = .{
.@"comptime" = .{
.constant_array = try unit.constant_arrays.append(context.my_allocator, .{
.values = values.slice(),
.type = array_type,
}),
},
},
.type = array_type,
};
},
else => {
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) { break :block switch (side) {
@ -9892,6 +9967,8 @@ pub const Builder = struct {
}, },
}; };
}, },
}
},
.compare_equal, .compare_equal,
.compare_not_equal, .compare_not_equal,
.compare_greater, .compare_greater,

View File

@ -2693,6 +2693,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const cast_instruction = llvm.builder.createCast(cast_type, value, value.getType(), cast_name.ptr, cast_name.len) orelse return LLVM.Value.Instruction.Error.cast; const cast_instruction = llvm.builder.createCast(cast_type, value, value.getType(), cast_name.ptr, cast_name.len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, cast_instruction); try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, cast_instruction);
}, },
.array_bitcast_to_integer => unreachable,
// TODO: Poke metadata // TODO: Poke metadata
.pointer_var_to_const, .pointer_var_to_const,
.slice_var_to_const, .slice_var_to_const,

View File

@ -0,0 +1,6 @@
const std = #import("std");
const expect = std.testing.expect;
const main = fn () *!void {
const a: u64 = #cast("comptime".@);
try expect(a == 7308613719115525987);
}