| author | |
| committer | |
| log | f7835000b62fb5b501f1d84c90f56e2aa11bc55a |
| tree | 92a0b659ac6f077359ba1e5fbdc1c1de86b297e6 |
| parent | ea5cedced1aa6bb5e1c1a07fcd16c5bed08c971f |
| signature |
5 files changed, 15 insertions(+), 16 deletions(-)
doc/langref.html.in+6-5| ... | @@ -6116,7 +6116,7 @@ test "main" { | ... | @@ -6116,7 +6116,7 @@ test "main" { |
| 6116 | {#header_close#} | 6116 | {#header_close#} |
| 6117 | 6117 | ||
| 6118 | {#header_open|@frameAddress#} | 6118 | {#header_open|@frameAddress#} |
| 6119 | <pre>{#syntax#}@frameAddress(){#endsyntax#}</pre> | 6119 | <pre>{#syntax#}@frameAddress() usize{#endsyntax#}</pre> |
| 6120 | <p> | 6120 | <p> |
| 6121 | This function returns the base pointer of the current stack frame. | 6121 | This function returns the base pointer of the current stack frame. |
| 6122 | </p> | 6122 | </p> |
| ... | @@ -6482,17 +6482,18 @@ test "call foo" { | ... | @@ -6482,17 +6482,18 @@ test "call foo" { |
| 6482 | {#header_close#} | 6482 | {#header_close#} |
| 6483 | 6483 | ||
| 6484 | {#header_open|@returnAddress#} | 6484 | {#header_open|@returnAddress#} |
| 6485 | <pre>{#syntax#}@returnAddress(){#endsyntax#}</pre> | 6485 | <pre>{#syntax#}@returnAddress() usize{#endsyntax#}</pre> |
| 6486 | <p> | 6486 | <p> |
| 6487 | This function returns a pointer to the return address of the current stack | 6487 | This function returns the address of the next machine code instruction that will be executed |
| 6488 | frame. | 6488 | when the current function returns. |
| 6489 | </p> | 6489 | </p> |
| 6490 | <p> | 6490 | <p> |
| 6491 | The implications of this are target specific and not consistent across | 6491 | The implications of this are target specific and not consistent across |
| 6492 | all platforms. | 6492 | all platforms. |
| 6493 | </p> | 6493 | </p> |
| 6494 | <p> | 6494 | <p> |
| 6495 | This function is only valid within function scope. | 6495 | This function is only valid within function scope. If the function gets inlined into |
| 6496 | a calling function, the returned address will apply to the calling function. | ||
| 6496 | </p> | 6497 | </p> |
| 6497 | {#header_close#} | 6498 | {#header_close#} |
| 6498 | {#header_open|@setAlignStack#} | 6499 | {#header_open|@setAlignStack#} |
src/codegen.cpp+4-2| ... | @@ -4661,7 +4661,8 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executabl | ... | @@ -4661,7 +4661,8 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executabl |
| 4661 | IrInstructionReturnAddress *instruction) | 4661 | IrInstructionReturnAddress *instruction) |
| 4662 | { | 4662 | { |
| 4663 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); | 4663 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); |
| 4664 | return LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); | 4664 | LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); |
| 4665 | return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->type_ref, ""); | ||
| 4665 | } | 4666 | } |
| 4666 | 4667 | ||
| 4667 | static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { | 4668 | static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { |
| ... | @@ -4682,7 +4683,8 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable | ... | @@ -4682,7 +4683,8 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable |
| 4682 | IrInstructionFrameAddress *instruction) | 4683 | IrInstructionFrameAddress *instruction) |
| 4683 | { | 4684 | { |
| 4684 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); | 4685 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); |
| 4685 | return LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, ""); | 4686 | LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, ""); |
| 4687 | return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->type_ref, ""); | ||
| 4686 | } | 4688 | } |
| 4687 | 4689 | ||
| 4688 | static LLVMValueRef get_handle_fn_val(CodeGen *g) { | 4690 | static LLVMValueRef get_handle_fn_val(CodeGen *g) { |
src/ir.cpp+2-6| ... | @@ -20142,18 +20142,14 @@ static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstru | ... | @@ -20142,18 +20142,14 @@ static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstru |
| 20142 | static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { | 20142 | static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { |
| 20143 | IrInstruction *result = ir_build_return_address(&ira->new_irb, | 20143 | IrInstruction *result = ir_build_return_address(&ira->new_irb, |
| 20144 | instruction->base.scope, instruction->base.source_node); | 20144 | instruction->base.scope, instruction->base.source_node); |
| 20145 | ZigType *u8 = ira->codegen->builtin_types.entry_u8; | 20145 | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 20146 | ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); | ||
| 20147 | result->value.type = u8_ptr_const; | ||
| 20148 | return result; | 20146 | return result; |
| 20149 | } | 20147 | } |
| 20150 | 20148 | ||
| 20151 | static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { | 20149 | static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { |
| 20152 | IrInstruction *result = ir_build_frame_address(&ira->new_irb, | 20150 | IrInstruction *result = ir_build_frame_address(&ira->new_irb, |
| 20153 | instruction->base.scope, instruction->base.source_node); | 20151 | instruction->base.scope, instruction->base.source_node); |
| 20154 | ZigType *u8 = ira->codegen->builtin_types.entry_u8; | 20152 | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 20155 | ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); | ||
| 20156 | result->value.type = u8_ptr_const; | ||
| 20157 | return result; | 20153 | return result; |
| 20158 | } | 20154 | } |
| 20159 | 20155 |
std/debug/index.zig+2-2| ... | @@ -171,7 +171,7 @@ pub fn assert(ok: bool) void { | ... | @@ -171,7 +171,7 @@ pub fn assert(ok: bool) void { |
| 171 | 171 | ||
| 172 | pub fn panic(comptime format: []const u8, args: ...) noreturn { | 172 | pub fn panic(comptime format: []const u8, args: ...) noreturn { |
| 173 | @setCold(true); | 173 | @setCold(true); |
| 174 | const first_trace_addr = @ptrToInt(@returnAddress()); | 174 | const first_trace_addr = @returnAddress(); |
| 175 | panicExtra(null, first_trace_addr, format, args); | 175 | panicExtra(null, first_trace_addr, format, args); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| ... | @@ -232,7 +232,7 @@ pub const StackIterator = struct { | ... | @@ -232,7 +232,7 @@ pub const StackIterator = struct { |
| 232 | pub fn init(first_addr: ?usize) StackIterator { | 232 | pub fn init(first_addr: ?usize) StackIterator { |
| 233 | return StackIterator{ | 233 | return StackIterator{ |
| 234 | .first_addr = first_addr, | 234 | .first_addr = first_addr, |
| 235 | .fp = @ptrToInt(@frameAddress()), | 235 | .fp = @frameAddress(), |
| 236 | }; | 236 | }; |
| 237 | } | 237 | } |
| 238 | 238 |
std/special/panic.zig+1-1| ... | @@ -18,7 +18,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn | ... | @@ -18,7 +18,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn |
| 18 | std.os.abort(); | 18 | std.os.abort(); |
| 19 | }, | 19 | }, |
| 20 | else => { | 20 | else => { |
| 21 | const first_trace_addr = @ptrToInt(@returnAddress()); | 21 | const first_trace_addr = @returnAddress(); |
| 22 | std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg); | 22 | std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg); |
| 23 | }, | 23 | }, |
| 24 | } | 24 | } |