From 1b1921f0e26b9cb8ac78003c9061acac2da5e7ab Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 8 Aug 2020 01:00:29 -0700 Subject: [PATCH] stage1: deal with WebAssembly not supporting @returnAddress() This makes `@returnAddress()` return 0 for WebAssembly (when not using the Emscripten OS) and avoids trying to capture stack traces for the general purpose allocator on that target. --- lib/std/heap.zig | 11 +++++++++-- lib/std/heap/general_purpose_allocator.zig | 5 ++++- src/codegen.cpp | 6 ++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 88f27fad49..0c9dbca369 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -37,7 +37,7 @@ var c_allocator_state = Allocator{ .resizeFn = cResize, }; -fn cAlloc(self: *Allocator, len: usize, ptr_align: u29, len_align: u29) Allocator.Error![]u8 { +fn cAlloc(self: *Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Allocator.Error![]u8 { assert(ptr_align <= @alignOf(c_longdouble)); const ptr = @ptrCast([*]u8, c.malloc(len) orelse return error.OutOfMemory); if (len_align == 0) { @@ -54,7 +54,14 @@ fn cAlloc(self: *Allocator, len: usize, ptr_align: u29, len_align: u29) Allocato return ptr[0..mem.alignBackwardAnyAlign(full_len, len_align)]; } -fn cResize(self: *Allocator, buf: []u8, old_align: u29, new_len: usize, len_align: u29) Allocator.Error!usize { +fn cResize( + self: *Allocator, + buf: []u8, + old_align: u29, + new_len: usize, + len_align: u29, + ret_addr: usize, +) Allocator.Error!usize { if (new_len == 0) { c.free(buf.ptr); return 0; diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index 98f029579c..5369560356 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -102,9 +102,12 @@ const StackTrace = std.builtin.StackTrace; /// Integer type for pointing to slots in a small allocation const SlotIndex = std.meta.Int(false, math.log2(page_size) + 1); +// WebAssembly doesn't support stack tracing yet. +const default_stack_trace_frames: usize = if (std.Target.current.cpu.arch.isWasm()) 0 else 4; + pub const Config = struct { /// Number of stack frames to capture. - stack_trace_frames: usize = if (std.debug.runtime_safety) @as(usize, 4) else @as(usize, 0), + stack_trace_frames: usize = if (std.debug.runtime_safety) default_stack_trace_frames else @as(usize, 0), /// If true, the allocator will have two fields: /// * `total_requested_bytes` which tracks the total allocated bytes of memory requested. diff --git a/src/codegen.cpp b/src/codegen.cpp index 023c94f245..6941eae466 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5886,6 +5886,12 @@ static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutableGen *executable static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutableGen *executable, IrInstGenReturnAddress *instruction) { + if (target_is_wasm(g->zig_target) && g->zig_target->os != OsEmscripten) { + // I got this error from LLVM 10: + // "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address" + return LLVMConstNull(get_llvm_type(g, instruction->base.value->type)); + } + LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");