coerce in memory improvements
This commit is contained in:
parent
bdf143eaa6
commit
3d95b203f2
@ -1889,14 +1889,12 @@ const InMemoryCoercionResult = union(enum) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// If pointers have the same representation in runtime memory
|
/// If types have the same representation in runtime memory
|
||||||
/// * `const` attribute can be gained
|
/// * int/float: same number of bits
|
||||||
/// * `volatile` attribute can be gained
|
/// * pointer: see `coerceInMemoryAllowedPtrs`
|
||||||
/// * `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) but only if dest_is_const
|
/// * error union: coerceable error set and payload
|
||||||
/// * alignment can be decreased
|
/// * error set: sub-set to super-set
|
||||||
/// * bit offset attributes must match exactly
|
/// * array: same shape and coerceable child
|
||||||
/// * `*`/`[*]` must match exactly, but `[*c]` matches either one
|
|
||||||
/// * sentinel-terminated pointers can coerce into `[*]`
|
|
||||||
fn coerceInMemoryAllowed(
|
fn coerceInMemoryAllowed(
|
||||||
ip: *InternPool,
|
ip: *InternPool,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
@ -1928,12 +1926,19 @@ fn coerceInMemoryAllowed(
|
|||||||
|
|
||||||
if (dest_info.signedness == src_info.signedness and dest_info.bits == src_info.bits) return .ok;
|
if (dest_info.signedness == src_info.signedness and dest_info.bits == src_info.bits) return .ok;
|
||||||
|
|
||||||
return InMemoryCoercionResult{ .int_not_coercible = .{
|
if ((src_info.signedness == dest_info.signedness and dest_info.bits < src_info.bits) or
|
||||||
.actual_signedness = src_info.signedness,
|
// small enough unsigned ints can get casted to large enough signed ints
|
||||||
.wanted_signedness = dest_info.signedness,
|
(dest_info.signedness == .signed and (src_info.signedness == .unsigned or dest_info.bits <= src_info.bits)) or
|
||||||
.actual_bits = src_info.bits,
|
(dest_info.signedness == .unsigned and src_info.signedness == .signed))
|
||||||
.wanted_bits = dest_info.bits,
|
{
|
||||||
} };
|
return InMemoryCoercionResult{ .int_not_coercible = .{
|
||||||
|
.actual_signedness = src_info.signedness,
|
||||||
|
.wanted_signedness = dest_info.signedness,
|
||||||
|
.actual_bits = src_info.bits,
|
||||||
|
.wanted_bits = dest_info.bits,
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
return .ok;
|
||||||
},
|
},
|
||||||
.Float => {
|
.Float => {
|
||||||
const dest_bits = dest_key.floatBits(target);
|
const dest_bits = dest_key.floatBits(target);
|
||||||
@ -2225,7 +2230,7 @@ fn coerceInMemoryAllowedFns(
|
|||||||
dest_info: Function,
|
dest_info: Function,
|
||||||
src_info: Function,
|
src_info: Function,
|
||||||
target: std.Target,
|
target: std.Target,
|
||||||
) !InMemoryCoercionResult {
|
) error{OutOfMemory}!InMemoryCoercionResult {
|
||||||
if (dest_info.is_var_args != src_info.is_var_args) {
|
if (dest_info.is_var_args != src_info.is_var_args) {
|
||||||
return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };
|
return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };
|
||||||
}
|
}
|
||||||
@ -2269,24 +2274,24 @@ fn coerceInMemoryAllowedFns(
|
|||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dest_info.args) |dest_param_ty, i| {
|
if (!dest_info.args_is_comptime.eql(src_info.args_is_comptime)) {
|
||||||
const src_param_ty = src_info.args[i];
|
const index = dest_info.args_is_comptime.xorWith(src_info.args_is_comptime).findFirstSet().?;
|
||||||
|
return InMemoryCoercionResult{ .fn_param_comptime = .{
|
||||||
|
.index = index,
|
||||||
|
.wanted = dest_info.args_is_comptime.isSet(index),
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
// TODO move outside of loop
|
for (dest_info.args) |dest_arg_ty, i| {
|
||||||
if (i < 32 and dest_info.args_is_comptime.isSet(i) != src_info.args_is_comptime.isSet(i)) {
|
const src_arg_ty = src_info.args[i];
|
||||||
return InMemoryCoercionResult{ .fn_param_comptime = .{
|
|
||||||
.index = i,
|
|
||||||
.wanted = dest_info.args_is_comptime.isSet(i),
|
|
||||||
} };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: Cast direction is reversed here.
|
// Note: Cast direction is reversed here.
|
||||||
const param = try ip.coerceInMemoryAllowed(gpa, arena, src_param_ty, dest_param_ty, true, target);
|
const param = try ip.coerceInMemoryAllowed(gpa, arena, src_arg_ty, dest_arg_ty, true, target);
|
||||||
if (param != .ok) {
|
if (param != .ok) {
|
||||||
return InMemoryCoercionResult{ .fn_param = .{
|
return InMemoryCoercionResult{ .fn_param = .{
|
||||||
.child = try param.dupe(arena),
|
.child = try param.dupe(arena),
|
||||||
.actual = src_param_ty,
|
.actual = src_arg_ty,
|
||||||
.wanted = dest_param_ty,
|
.wanted = dest_arg_ty,
|
||||||
.index = i,
|
.index = i,
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
@ -2295,6 +2300,14 @@ fn coerceInMemoryAllowedFns(
|
|||||||
return .ok;
|
return .ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If pointers have the same representation in runtime memory
|
||||||
|
/// * `const` attribute can be gained
|
||||||
|
/// * `volatile` attribute can be gained
|
||||||
|
/// * `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) but only if dest_is_const
|
||||||
|
/// * alignment can be decreased
|
||||||
|
/// * bit offset attributes must match exactly
|
||||||
|
/// * `*`/`[*]` must match exactly, but `[*c]` matches either one
|
||||||
|
/// * sentinel-terminated pointers can coerce into `[*]`
|
||||||
fn coerceInMemoryAllowedPtrs(
|
fn coerceInMemoryAllowedPtrs(
|
||||||
ip: *InternPool,
|
ip: *InternPool,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
@ -2305,7 +2318,7 @@ fn coerceInMemoryAllowedPtrs(
|
|||||||
src_ptr_info: Key,
|
src_ptr_info: Key,
|
||||||
dest_is_const: bool,
|
dest_is_const: bool,
|
||||||
target: std.Target,
|
target: std.Target,
|
||||||
) !InMemoryCoercionResult {
|
) error{OutOfMemory}!InMemoryCoercionResult {
|
||||||
const dest_info = dest_ptr_info.pointer_type;
|
const dest_info = dest_ptr_info.pointer_type;
|
||||||
const src_info = src_ptr_info.pointer_type;
|
const src_info = src_ptr_info.pointer_type;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user