mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-07 22:34:28 +00:00
parent
3ca027ca82
commit
f8e63c4584
15 changed files with 91 additions and 82 deletions
|
|
@ -634,9 +634,6 @@ calls the public `panic` function exposed in the root source file, or
|
||||||
if there is not one specified, invokes the one provided in
|
if there is not one specified, invokes the one provided in
|
||||||
`std/special/panic.zig`.
|
`std/special/panic.zig`.
|
||||||
|
|
||||||
### @bitcast(comptime DestType: type, value: var) -> DestType
|
### @ptrcast(comptime DestType: type, value: var) -> DestType
|
||||||
|
|
||||||
Transmutes memory from one type to another without changing any bits.
|
Converts a pointer of one type to a pointer of another type.
|
||||||
The source and destination types must have the same size. This function
|
|
||||||
can be used to, for example, reinterpret a pointer, or convert a `f32` to a
|
|
||||||
`u32`.
|
|
||||||
|
|
|
||||||
|
|
@ -1196,7 +1196,7 @@ enum BuiltinFnId {
|
||||||
BuiltinFnIdSetGlobalSection,
|
BuiltinFnIdSetGlobalSection,
|
||||||
BuiltinFnIdSetGlobalLinkage,
|
BuiltinFnIdSetGlobalLinkage,
|
||||||
BuiltinFnIdPanic,
|
BuiltinFnIdPanic,
|
||||||
BuiltinFnIdBitCast,
|
BuiltinFnIdPtrCast,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuiltinFnEntry {
|
struct BuiltinFnEntry {
|
||||||
|
|
@ -1720,7 +1720,7 @@ enum IrInstructionId {
|
||||||
IrInstructionIdFnProto,
|
IrInstructionIdFnProto,
|
||||||
IrInstructionIdTestComptime,
|
IrInstructionIdTestComptime,
|
||||||
IrInstructionIdInitEnum,
|
IrInstructionIdInitEnum,
|
||||||
IrInstructionIdBitCast,
|
IrInstructionIdPtrCast,
|
||||||
IrInstructionIdWidenOrShorten,
|
IrInstructionIdWidenOrShorten,
|
||||||
IrInstructionIdIntToPtr,
|
IrInstructionIdIntToPtr,
|
||||||
IrInstructionIdPtrToInt,
|
IrInstructionIdPtrToInt,
|
||||||
|
|
@ -2370,11 +2370,11 @@ struct IrInstructionInitEnum {
|
||||||
LLVMValueRef tmp_ptr;
|
LLVMValueRef tmp_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstructionBitCast {
|
struct IrInstructionPtrCast {
|
||||||
IrInstruction base;
|
IrInstruction base;
|
||||||
|
|
||||||
IrInstruction *dest_type;
|
IrInstruction *dest_type;
|
||||||
IrInstruction *target;
|
IrInstruction *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstructionWidenOrShorten {
|
struct IrInstructionWidenOrShorten {
|
||||||
|
|
|
||||||
|
|
@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable,
|
static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
|
||||||
IrInstructionBitCast *instruction)
|
IrInstructionPtrCast *instruction)
|
||||||
{
|
{
|
||||||
TypeTableEntry *wanted_type = instruction->base.value.type;
|
TypeTableEntry *wanted_type = instruction->base.value.type;
|
||||||
LLVMValueRef target = ir_llvm_value(g, instruction->target);
|
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
|
||||||
return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, "");
|
return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
|
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
|
||||||
|
|
@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||||
return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
|
return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
|
||||||
case IrInstructionIdStructInit:
|
case IrInstructionIdStructInit:
|
||||||
return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
|
return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
|
||||||
case IrInstructionIdBitCast:
|
case IrInstructionIdPtrCast:
|
||||||
return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction);
|
return ir_render_ptr_cast(g, executable, (IrInstructionPtrCast *)instruction);
|
||||||
case IrInstructionIdWidenOrShorten:
|
case IrInstructionIdWidenOrShorten:
|
||||||
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
|
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
|
||||||
case IrInstructionIdPtrToInt:
|
case IrInstructionIdPtrToInt:
|
||||||
|
|
@ -4260,7 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||||
create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
|
create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
|
||||||
create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
|
create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
|
||||||
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
|
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
|
||||||
create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2);
|
create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
|
static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
|
||||||
|
|
|
||||||
72
src/ir.cpp
72
src/ir.cpp
|
|
@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
|
||||||
return IrInstructionIdInitEnum;
|
return IrInstructionIdInitEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) {
|
||||||
return IrInstructionIdBitCast;
|
return IrInstructionIdPtrCast;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
|
||||||
|
|
@ -1940,16 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
|
||||||
return new_instruction;
|
return new_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||||
IrInstruction *dest_type, IrInstruction *target)
|
IrInstruction *dest_type, IrInstruction *ptr)
|
||||||
{
|
{
|
||||||
IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
|
IrInstructionPtrCast *instruction = ir_build_instruction<IrInstructionPtrCast>(
|
||||||
irb, scope, source_node);
|
irb, scope, source_node);
|
||||||
instruction->dest_type = dest_type;
|
instruction->dest_type = dest_type;
|
||||||
instruction->target = target;
|
instruction->ptr = ptr;
|
||||||
|
|
||||||
if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
|
if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
|
||||||
ir_ref_instruction(target, irb->current_basic_block);
|
ir_ref_instruction(ptr, irb->current_basic_block);
|
||||||
|
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
@ -2666,12 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
|
static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instruction,
|
||||||
size_t index)
|
size_t index)
|
||||||
{
|
{
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: return instruction->dest_type;
|
case 0: return instruction->dest_type;
|
||||||
case 1: return instruction->target;
|
case 1: return instruction->ptr;
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2928,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
|
||||||
return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
|
return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
|
||||||
case IrInstructionIdInitEnum:
|
case IrInstructionIdInitEnum:
|
||||||
return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
|
return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
|
||||||
case IrInstructionIdBitCast:
|
case IrInstructionIdPtrCast:
|
||||||
return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
|
return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index);
|
||||||
case IrInstructionIdWidenOrShorten:
|
case IrInstructionIdWidenOrShorten:
|
||||||
return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
|
return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
|
||||||
case IrInstructionIdIntToPtr:
|
case IrInstructionIdIntToPtr:
|
||||||
|
|
@ -4200,7 +4200,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
||||||
|
|
||||||
return ir_build_panic(irb, scope, node, arg0_value);
|
return ir_build_panic(irb, scope, node, arg0_value);
|
||||||
}
|
}
|
||||||
case BuiltinFnIdBitCast:
|
case BuiltinFnIdPtrCast:
|
||||||
{
|
{
|
||||||
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
|
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
|
||||||
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
|
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
|
||||||
|
|
@ -4212,7 +4212,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
||||||
if (arg1_value == irb->codegen->invalid_instruction)
|
if (arg1_value == irb->codegen->invalid_instruction)
|
||||||
return arg1_value;
|
return arg1_value;
|
||||||
|
|
||||||
return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
|
return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
|
|
@ -12182,34 +12182,36 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
|
||||||
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
|
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
|
static bool is_ptr_type(TypeTableEntry *t) {
|
||||||
|
return (t->id == TypeTableEntryIdPointer || t->id == TypeTableEntryIdFn ||
|
||||||
|
(t->id == TypeTableEntryIdMaybe && (t->data.maybe.child_type->id == TypeTableEntryIdPointer ||
|
||||||
|
t->data.maybe.child_type->id == TypeTableEntryIdFn)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCast *instruction) {
|
||||||
IrInstruction *dest_type_value = instruction->dest_type->other;
|
IrInstruction *dest_type_value = instruction->dest_type->other;
|
||||||
TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
|
TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
|
||||||
if (type_is_invalid(dest_type))
|
if (type_is_invalid(dest_type))
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
|
|
||||||
IrInstruction *target = instruction->target->other;
|
IrInstruction *ptr = instruction->ptr->other;
|
||||||
TypeTableEntry *src_type = target->value.type;
|
TypeTableEntry *src_type = ptr->value.type;
|
||||||
if (type_is_invalid(src_type))
|
if (type_is_invalid(src_type))
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
|
|
||||||
ensure_complete_type(ira->codegen, dest_type);
|
if (!is_ptr_type(src_type)) {
|
||||||
ensure_complete_type(ira->codegen, src_type);
|
ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name)));
|
||||||
|
|
||||||
uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
|
|
||||||
uint64_t src_size_bytes = type_size(ira->codegen, src_type);
|
|
||||||
if (dest_size_bytes != src_size_bytes) {
|
|
||||||
ir_add_error(ira, &instruction->base,
|
|
||||||
buf_sprintf("destination type '%s' has size %" PRIu64 " but source type '%s' has size %" PRIu64,
|
|
||||||
buf_ptr(&dest_type->name), dest_size_bytes,
|
|
||||||
buf_ptr(&src_type->name), src_size_bytes));
|
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr_is_comptime(target) && src_type->id == dest_type->id &&
|
if (!is_ptr_type(dest_type)) {
|
||||||
(src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe))
|
ir_add_error(ira, dest_type_value,
|
||||||
{
|
buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
|
||||||
ConstExprValue *val = ir_resolve_const(ira, target, UndefOk);
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instr_is_comptime(ptr)) {
|
||||||
|
ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
|
||||||
if (!val)
|
if (!val)
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
|
|
||||||
|
|
@ -12219,8 +12221,8 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
|
||||||
return dest_type;
|
return dest_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
|
IrInstruction *result = ir_build_ptr_cast(&ira->new_irb, instruction->base.scope,
|
||||||
instruction->base.source_node, nullptr, target);
|
instruction->base.source_node, nullptr, ptr);
|
||||||
ir_link_new_instruction(result, &instruction->base);
|
ir_link_new_instruction(result, &instruction->base);
|
||||||
result->value.type = dest_type;
|
result->value.type = dest_type;
|
||||||
return dest_type;
|
return dest_type;
|
||||||
|
|
@ -12464,8 +12466,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
|
||||||
return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
|
return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
|
||||||
case IrInstructionIdPanic:
|
case IrInstructionIdPanic:
|
||||||
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
|
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
|
||||||
case IrInstructionIdBitCast:
|
case IrInstructionIdPtrCast:
|
||||||
return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
|
return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);
|
||||||
case IrInstructionIdMaybeWrap:
|
case IrInstructionIdMaybeWrap:
|
||||||
case IrInstructionIdErrWrapCode:
|
case IrInstructionIdErrWrapCode:
|
||||||
case IrInstructionIdErrWrapPayload:
|
case IrInstructionIdErrWrapPayload:
|
||||||
|
|
@ -12637,7 +12639,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
||||||
case IrInstructionIdFnProto:
|
case IrInstructionIdFnProto:
|
||||||
case IrInstructionIdTestComptime:
|
case IrInstructionIdTestComptime:
|
||||||
case IrInstructionIdInitEnum:
|
case IrInstructionIdInitEnum:
|
||||||
case IrInstructionIdBitCast:
|
case IrInstructionIdPtrCast:
|
||||||
case IrInstructionIdWidenOrShorten:
|
case IrInstructionIdWidenOrShorten:
|
||||||
case IrInstructionIdPtrToInt:
|
case IrInstructionIdPtrToInt:
|
||||||
case IrInstructionIdIntToPtr:
|
case IrInstructionIdIntToPtr:
|
||||||
|
|
|
||||||
|
|
@ -765,9 +765,13 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)
|
||||||
fprintf(irp->f, "}");
|
fprintf(irp->f, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
|
static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) {
|
||||||
fprintf(irp->f, "@bitcast(");
|
fprintf(irp->f, "@ptrcast(");
|
||||||
ir_print_other_instruction(irp, instruction->target);
|
if (instruction->dest_type) {
|
||||||
|
ir_print_other_instruction(irp, instruction->dest_type);
|
||||||
|
}
|
||||||
|
fprintf(irp->f, ",");
|
||||||
|
ir_print_other_instruction(irp, instruction->ptr);
|
||||||
fprintf(irp->f, ")");
|
fprintf(irp->f, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1098,8 +1102,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
case IrInstructionIdInitEnum:
|
case IrInstructionIdInitEnum:
|
||||||
ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
|
ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
|
||||||
break;
|
break;
|
||||||
case IrInstructionIdBitCast:
|
case IrInstructionIdPtrCast:
|
||||||
ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
|
ir_print_ptr_cast(irp, (IrInstructionPtrCast *)instruction);
|
||||||
break;
|
break;
|
||||||
case IrInstructionIdWidenOrShorten:
|
case IrInstructionIdWidenOrShorten:
|
||||||
ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
|
ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
|
||||||
const name = %return compile_unit.die.getAttrString(st, DW.AT_name);
|
const name = %return compile_unit.die.getAttrString(st, DW.AT_name);
|
||||||
|
|
||||||
%return out_stream.printf("{} -> {}\n", return_address, name);
|
%return out_stream.printf("{} -> {}\n", return_address, name);
|
||||||
maybe_fp = *@bitcast(&const ?&const u8, fp);
|
maybe_fp = *@ptrcast(&const ?&const u8, fp);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ObjectFormat.coff => {
|
ObjectFormat.coff => {
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ test "basicHashMapTest" {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_i32(x: i32) -> u32 {
|
fn hash_i32(x: i32) -> u32 {
|
||||||
*@bitcast(&u32, &x)
|
*@ptrcast(&u32, &x)
|
||||||
}
|
}
|
||||||
fn eql_i32(a: i32, b: i32) -> bool {
|
fn eql_i32(a: i32, b: i32) -> bool {
|
||||||
a == b
|
a == b
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ pub const IncrementingAllocator = struct {
|
||||||
fn alloc(allocator: &Allocator, n: usize) -> %[]u8 {
|
fn alloc(allocator: &Allocator, n: usize) -> %[]u8 {
|
||||||
// TODO
|
// TODO
|
||||||
//const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
|
//const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
|
||||||
const self = @bitcast(&IncrementingAllocator, allocator);
|
const self = @ptrcast(&IncrementingAllocator, allocator);
|
||||||
const new_end_index = self.end_index + n;
|
const new_end_index = self.end_index + n;
|
||||||
if (new_end_index > self.bytes.len) {
|
if (new_end_index > self.bytes.len) {
|
||||||
return error.NoMem;
|
return error.NoMem;
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ pub const AF_MAX = PF_MAX;
|
||||||
|
|
||||||
/// Get the errno from a syscall return value, or 0 for no error.
|
/// Get the errno from a syscall return value, or 0 for no error.
|
||||||
pub fn getErrno(r: usize) -> usize {
|
pub fn getErrno(r: usize) -> usize {
|
||||||
const signed_r = *@bitcast(&isize, &r);
|
const signed_r = *@ptrcast(&isize, &r);
|
||||||
if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
|
if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int {
|
||||||
|
|
||||||
fn du_int_to_udwords(x: du_int) -> udwords {
|
fn du_int_to_udwords(x: du_int) -> udwords {
|
||||||
@setDebugSafety(this, false);
|
@setDebugSafety(this, false);
|
||||||
return *@bitcast(&udwords, &x);
|
return *@ptrcast(&udwords, &x);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
|
|
@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
if (var rem ?= maybe_rem) {
|
if (var rem ?= maybe_rem) {
|
||||||
r[high] = n[high] % d[high];
|
r[high] = n[high] % d[high];
|
||||||
r[low] = 0;
|
r[low] = 0;
|
||||||
*rem = *@bitcast(&du_int, &r[0]);
|
*rem = *@ptrcast(&du_int, &r[0]);
|
||||||
}
|
}
|
||||||
return n[high] / d[high];
|
return n[high] / d[high];
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
if (var rem ?= maybe_rem) {
|
if (var rem ?= maybe_rem) {
|
||||||
r[low] = n[low];
|
r[low] = n[low];
|
||||||
r[high] = n[high] & (d[high] - 1);
|
r[high] = n[high] & (d[high] - 1);
|
||||||
*rem = *@bitcast(&du_int, &r[0]);
|
*rem = *@ptrcast(&du_int, &r[0]);
|
||||||
}
|
}
|
||||||
return n[high] >> @ctz(d[high]);
|
return n[high] >> @ctz(d[high]);
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
// 0 <= sr <= n_uword_bits - 2 or sr large
|
// 0 <= sr <= n_uword_bits - 2 or sr large
|
||||||
if (sr > n_uword_bits - 2) {
|
if (sr > n_uword_bits - 2) {
|
||||||
if (var rem ?= maybe_rem) {
|
if (var rem ?= maybe_rem) {
|
||||||
*rem = *@bitcast(&du_int, &n[0]);
|
*rem = *@ptrcast(&du_int, &n[0]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
*rem = n[low] & (d[low] - 1);
|
*rem = n[low] & (d[low] - 1);
|
||||||
}
|
}
|
||||||
if (d[low] == 1) {
|
if (d[low] == 1) {
|
||||||
return *@bitcast(&du_int, &n[0]);
|
return *@ptrcast(&du_int, &n[0]);
|
||||||
}
|
}
|
||||||
sr = @ctz(d[low]);
|
sr = @ctz(d[low]);
|
||||||
q[high] = n[high] >> sr;
|
q[high] = n[high] >> sr;
|
||||||
q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
|
q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
|
||||||
return *@bitcast(&du_int, &q[0]);
|
return *@ptrcast(&du_int, &q[0]);
|
||||||
}
|
}
|
||||||
// K X
|
// K X
|
||||||
// ---
|
// ---
|
||||||
|
|
@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
// 0 <= sr <= n_uword_bits - 1 or sr large
|
// 0 <= sr <= n_uword_bits - 1 or sr large
|
||||||
if (sr > n_uword_bits - 1) {
|
if (sr > n_uword_bits - 1) {
|
||||||
if (var rem ?= maybe_rem) {
|
if (var rem ?= maybe_rem) {
|
||||||
*rem = *@bitcast(&du_int, &n[0]);
|
*rem = *@ptrcast(&du_int, &n[0]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||||
// r.all -= d.all;
|
// r.all -= d.all;
|
||||||
// carry = 1;
|
// carry = 1;
|
||||||
// }
|
// }
|
||||||
const s: di_int = (di_int)(*@bitcast(&du_int, &d[0]) - *@bitcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
|
const s: di_int = (di_int)(*@ptrcast(&du_int, &d[0]) - *@ptrcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
|
||||||
carry = su_int(s & 1);
|
carry = su_int(s & 1);
|
||||||
*@bitcast(&du_int, &r[0]) -= *@bitcast(&du_int, &d[0]) & u64(s);
|
*@ptrcast(&du_int, &r[0]) -= *@ptrcast(&du_int, &d[0]) & u64(s);
|
||||||
|
|
||||||
sr -= 1;
|
sr -= 1;
|
||||||
}
|
}
|
||||||
*@bitcast(&du_int, &q[0]) = (*@bitcast(&du_int, &q[0]) << 1) | u64(carry);
|
*@ptrcast(&du_int, &q[0]) = (*@ptrcast(&du_int, &q[0]) << 1) | u64(carry);
|
||||||
if (var rem ?= maybe_rem) {
|
if (var rem ?= maybe_rem) {
|
||||||
*rem = *@bitcast(&du_int, &r[0]);
|
*rem = *@ptrcast(&du_int, &r[0]);
|
||||||
}
|
}
|
||||||
return *@bitcast(&du_int, &q[0]);
|
return *@ptrcast(&du_int, &q[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn __umoddi3(a: du_int, b: du_int) -> du_int {
|
export fn __umoddi3(a: du_int, b: du_int) -> du_int {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ test "numLitIntToPtrCast" {
|
||||||
test "pointerReinterpretConstFloatToInt" {
|
test "pointerReinterpretConstFloatToInt" {
|
||||||
const float: f64 = 5.99999999999994648725e-01;
|
const float: f64 = 5.99999999999994648725e-01;
|
||||||
const float_ptr = &float;
|
const float_ptr = &float;
|
||||||
const int_ptr = @bitcast(&i32, float_ptr);
|
const int_ptr = @ptrcast(&i32, float_ptr);
|
||||||
const int_val = *int_ptr;
|
const int_val = *int_ptr;
|
||||||
assert(int_val == 858993411);
|
assert(int_val == 858993411);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" {
|
||||||
}
|
}
|
||||||
fn getByte(ptr: ?&const u8) -> u8 {*??ptr}
|
fn getByte(ptr: ?&const u8) -> u8 {*??ptr}
|
||||||
fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
|
fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
|
||||||
getByte(@bitcast(&const u8, &mem[0]))
|
getByte(@ptrcast(&const u8, &mem[0]))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,15 +246,15 @@ test "typeEquality" {
|
||||||
|
|
||||||
const global_a: i32 = 1234;
|
const global_a: i32 = 1234;
|
||||||
const global_b: &const i32 = &global_a;
|
const global_b: &const i32 = &global_a;
|
||||||
const global_c: &const f32 = @bitcast(&const f32, global_b);
|
const global_c: &const f32 = @ptrcast(&const f32, global_b);
|
||||||
test "compileTimeGlobalReinterpret" {
|
test "compileTimeGlobalReinterpret" {
|
||||||
const d = @bitcast(&const i32, global_c);
|
const d = @ptrcast(&const i32, global_c);
|
||||||
assert(*d == 1234);
|
assert(*d == 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "explicitCastMaybePointers" {
|
test "explicitCastMaybePointers" {
|
||||||
const a: ?&i32 = undefined;
|
const a: ?&i32 = undefined;
|
||||||
const b: ?&f32 = @bitcast(?&f32, a);
|
const b: ?&f32 = @ptrcast(?&f32, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "genericMallocFree" {
|
test "genericMallocFree" {
|
||||||
|
|
@ -263,7 +263,7 @@ test "genericMallocFree" {
|
||||||
}
|
}
|
||||||
const some_mem : [100]u8 = undefined;
|
const some_mem : [100]u8 = undefined;
|
||||||
fn memAlloc(comptime T: type, n: usize) -> %[]T {
|
fn memAlloc(comptime T: type, n: usize) -> %[]T {
|
||||||
return @bitcast(&T, &some_mem[0])[0...n];
|
return @ptrcast(&T, &some_mem[0])[0...n];
|
||||||
}
|
}
|
||||||
fn memFree(comptime T: type, memory: []T) { }
|
fn memFree(comptime T: type, memory: []T) { }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct {
|
||||||
|
|
||||||
test "fn" {
|
test "fn" {
|
||||||
var foo: StructFoo = undefined;
|
var foo: StructFoo = undefined;
|
||||||
@memset(@bitcast(&u8, &foo), 0, @sizeOf(StructFoo));
|
@memset(@ptrcast(&u8, &foo), 0, @sizeOf(StructFoo));
|
||||||
foo.a += 1;
|
foo.a += 1;
|
||||||
foo.b = foo.a == 1;
|
foo.b = foo.a == 1;
|
||||||
testFoo(foo);
|
testFoo(foo);
|
||||||
|
|
|
||||||
|
|
@ -460,8 +460,8 @@ const foo : i32 = 0;
|
||||||
const c = @cImport(@cInclude("stdlib.h"));
|
const c = @cImport(@cInclude("stdlib.h"));
|
||||||
|
|
||||||
export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
|
export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
|
||||||
const a_int = @bitcast(&i32, a ?? unreachable);
|
const a_int = @ptrcast(&i32, a ?? unreachable);
|
||||||
const b_int = @bitcast(&i32, b ?? unreachable);
|
const b_int = @ptrcast(&i32, b ?? unreachable);
|
||||||
if (*a_int < *b_int) {
|
if (*a_int < *b_int) {
|
||||||
-1
|
-1
|
||||||
} else if (*a_int > *b_int) {
|
} else if (*a_int > *b_int) {
|
||||||
|
|
@ -474,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
|
||||||
export fn main(args: c_int, argv: &&u8) -> c_int {
|
export fn main(args: c_int, argv: &&u8) -> c_int {
|
||||||
var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
|
var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
|
||||||
|
|
||||||
c.qsort(@bitcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
|
c.qsort(@ptrcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
|
||||||
|
|
||||||
for (array) |item, i| {
|
for (array) |item, i| {
|
||||||
if (item != i) {
|
if (item != i) {
|
||||||
|
|
@ -1812,6 +1812,12 @@ export fn entry() {
|
||||||
foo(global_array);
|
foo(global_array);
|
||||||
}
|
}
|
||||||
)SOURCE", 1, ".tmp_source.zig:5:9: error: expected type '[]i32', found '[10]i32'");
|
)SOURCE", 1, ".tmp_source.zig:5:9: error: expected type '[]i32', found '[10]i32'");
|
||||||
|
|
||||||
|
add_compile_fail_case("ptrcast to non-pointer", R"SOURCE(
|
||||||
|
export fn entry(a: &i32) -> usize {
|
||||||
|
return @ptrcast(usize, a);
|
||||||
|
}
|
||||||
|
)SOURCE", 1, ".tmp_source.zig:3:21: error: expected pointer, found 'usize'");
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue