| ... | @@ -474,6 +474,10 @@ pub const SourceLocation = enum(u32) { | ... | @@ -474,6 +474,10 @@ pub const SourceLocation = enum(u32) { |
| 474 | err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl }; | 474 | err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl }; |
| 475 | } | 475 | } |
| 476 | | 476 | |
| | 477 | pub fn fail(sl: SourceLocation, diags: *link.Diags, comptime format: []const u8, args: anytype) error{LinkFailure} { |
| | 478 | return diags.failSourceLocation(.{ .wasm = sl }, format, args); |
| | 479 | } |
| | 480 | |
| 477 | pub fn string( | 481 | pub fn string( |
| 478 | sl: SourceLocation, | 482 | sl: SourceLocation, |
| 479 | msg: []const u8, | 483 | msg: []const u8, |
| ... | @@ -881,12 +885,11 @@ pub const FunctionImport = extern struct { | ... | @@ -881,12 +885,11 @@ pub const FunctionImport = extern struct { |
| 881 | __wasm_call_ctors, | 885 | __wasm_call_ctors, |
| 882 | __wasm_init_memory, | 886 | __wasm_init_memory, |
| 883 | __wasm_init_tls, | 887 | __wasm_init_tls, |
| 884 | __zig_error_names, | | |
| 885 | // Next, index into `object_functions`. | 888 | // Next, index into `object_functions`. |
| 886 | // Next, index into `zcu_funcs`. | 889 | // Next, index into `zcu_funcs`. |
| 887 | _, | 890 | _, |
| 888 | | 891 | |
| 889 | const first_object_function = @intFromEnum(Resolution.__zig_error_names) + 1; | 892 | const first_object_function = @intFromEnum(Resolution.__wasm_init_tls) + 1; |
| 890 | | 893 | |
| 891 | pub const Unpacked = union(enum) { | 894 | pub const Unpacked = union(enum) { |
| 892 | unresolved, | 895 | unresolved, |
| ... | @@ -894,7 +897,6 @@ pub const FunctionImport = extern struct { | ... | @@ -894,7 +897,6 @@ pub const FunctionImport = extern struct { |
| 894 | __wasm_call_ctors, | 897 | __wasm_call_ctors, |
| 895 | __wasm_init_memory, | 898 | __wasm_init_memory, |
| 896 | __wasm_init_tls, | 899 | __wasm_init_tls, |
| 897 | __zig_error_names, | | |
| 898 | object_function: ObjectFunctionIndex, | 900 | object_function: ObjectFunctionIndex, |
| 899 | zcu_func: ZcuFunc.Index, | 901 | zcu_func: ZcuFunc.Index, |
| 900 | }; | 902 | }; |
| ... | @@ -906,7 +908,6 @@ pub const FunctionImport = extern struct { | ... | @@ -906,7 +908,6 @@ pub const FunctionImport = extern struct { |
| 906 | .__wasm_call_ctors => .__wasm_call_ctors, | 908 | .__wasm_call_ctors => .__wasm_call_ctors, |
| 907 | .__wasm_init_memory => .__wasm_init_memory, | 909 | .__wasm_init_memory => .__wasm_init_memory, |
| 908 | .__wasm_init_tls => .__wasm_init_tls, | 910 | .__wasm_init_tls => .__wasm_init_tls, |
| 909 | .__zig_error_names => .__zig_error_names, | | |
| 910 | _ => { | 911 | _ => { |
| 911 | const object_function_index = @intFromEnum(r) - first_object_function; | 912 | const object_function_index = @intFromEnum(r) - first_object_function; |
| 912 | | 913 | |
| ... | @@ -927,7 +928,6 @@ pub const FunctionImport = extern struct { | ... | @@ -927,7 +928,6 @@ pub const FunctionImport = extern struct { |
| 927 | .__wasm_call_ctors => .__wasm_call_ctors, | 928 | .__wasm_call_ctors => .__wasm_call_ctors, |
| 928 | .__wasm_init_memory => .__wasm_init_memory, | 929 | .__wasm_init_memory => .__wasm_init_memory, |
| 929 | .__wasm_init_tls => .__wasm_init_tls, | 930 | .__wasm_init_tls => .__wasm_init_tls, |
| 930 | .__zig_error_names => .__zig_error_names, | | |
| 931 | .object_function => |i| @enumFromInt(first_object_function + @intFromEnum(i)), | 931 | .object_function => |i| @enumFromInt(first_object_function + @intFromEnum(i)), |
| 932 | .zcu_func => |i| @enumFromInt(first_object_function + wasm.object_functions.items.len + @intFromEnum(i)), | 932 | .zcu_func => |i| @enumFromInt(first_object_function + wasm.object_functions.items.len + @intFromEnum(i)), |
| 933 | }; | 933 | }; |
| ... | @@ -957,11 +957,11 @@ pub const FunctionImport = extern struct { | ... | @@ -957,11 +957,11 @@ pub const FunctionImport = extern struct { |
| 957 | pub fn typeIndex(r: Resolution, wasm: *Wasm) FunctionType.Index { | 957 | pub fn typeIndex(r: Resolution, wasm: *Wasm) FunctionType.Index { |
| 958 | return switch (unpack(r, wasm)) { | 958 | return switch (unpack(r, wasm)) { |
| 959 | .unresolved => unreachable, | 959 | .unresolved => unreachable, |
| 960 | .__wasm_apply_global_tls_relocs => @panic("TODO"), | 960 | .__wasm_apply_global_tls_relocs, |
| 961 | .__wasm_call_ctors => @panic("TODO"), | 961 | .__wasm_call_ctors, |
| 962 | .__wasm_init_memory => @panic("TODO"), | 962 | .__wasm_init_memory, |
| 963 | .__wasm_init_tls => @panic("TODO"), | 963 | => getExistingFuncType2(wasm, &.{}, &.{}), |
| 964 | .__zig_error_names => @panic("TODO"), | 964 | .__wasm_init_tls => getExistingFuncType2(wasm, &.{.i32}, &.{}), |
| 965 | .object_function => |i| i.ptr(wasm).type_index, | 965 | .object_function => |i| i.ptr(wasm).type_index, |
| 966 | .zcu_func => |i| i.typeIndex(wasm).?, | 966 | .zcu_func => |i| i.typeIndex(wasm).?, |
| 967 | }; | 967 | }; |
| ... | @@ -974,7 +974,6 @@ pub const FunctionImport = extern struct { | ... | @@ -974,7 +974,6 @@ pub const FunctionImport = extern struct { |
| 974 | .__wasm_call_ctors => @tagName(Unpacked.__wasm_call_ctors), | 974 | .__wasm_call_ctors => @tagName(Unpacked.__wasm_call_ctors), |
| 975 | .__wasm_init_memory => @tagName(Unpacked.__wasm_init_memory), | 975 | .__wasm_init_memory => @tagName(Unpacked.__wasm_init_memory), |
| 976 | .__wasm_init_tls => @tagName(Unpacked.__wasm_init_tls), | 976 | .__wasm_init_tls => @tagName(Unpacked.__wasm_init_tls), |
| 977 | .__zig_error_names => @tagName(Unpacked.__zig_error_names), | | |
| 978 | .object_function => |i| i.ptr(wasm).name.slice(wasm), | 977 | .object_function => |i| i.ptr(wasm).name.slice(wasm), |
| 979 | .zcu_func => |i| i.name(wasm), | 978 | .zcu_func => |i| i.name(wasm), |
| 980 | }; | 979 | }; |
| ... | @@ -2991,7 +2990,7 @@ fn markFunctionImport( | ... | @@ -2991,7 +2990,7 @@ fn markFunctionImport( |
| 2991 | name: String, | 2990 | name: String, |
| 2992 | import: *FunctionImport, | 2991 | import: *FunctionImport, |
| 2993 | func_index: FunctionImport.Index, | 2992 | func_index: FunctionImport.Index, |
| 2994 | ) Allocator.Error!void { | 2993 | ) link.File.FlushError!void { |
| 2995 | if (import.flags.alive) return; | 2994 | if (import.flags.alive) return; |
| 2996 | import.flags.alive = true; | 2995 | import.flags.alive = true; |
| 2997 | | 2996 | |
| ... | @@ -3002,17 +3001,13 @@ fn markFunctionImport( | ... | @@ -3002,17 +3001,13 @@ fn markFunctionImport( |
| 3002 | | 3001 | |
| 3003 | if (import.resolution == .unresolved) { | 3002 | if (import.resolution == .unresolved) { |
| 3004 | if (name == wasm.preloaded_strings.__wasm_init_memory) { | 3003 | if (name == wasm.preloaded_strings.__wasm_init_memory) { |
| 3005 | import.resolution = .__wasm_init_memory; | 3004 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_memory, &.{}, &.{}); |
| 3006 | wasm.functions.putAssumeCapacity(.__wasm_init_memory, {}); | | |
| 3007 | } else if (name == wasm.preloaded_strings.__wasm_apply_global_tls_relocs) { | 3005 | } else if (name == wasm.preloaded_strings.__wasm_apply_global_tls_relocs) { |
| 3008 | import.resolution = .__wasm_apply_global_tls_relocs; | 3006 | try wasm.resolveFunctionSynthetic(import, .__wasm_apply_global_tls_relocs, &.{}, &.{}); |
| 3009 | wasm.functions.putAssumeCapacity(.__wasm_apply_global_tls_relocs, {}); | | |
| 3010 | } else if (name == wasm.preloaded_strings.__wasm_call_ctors) { | 3007 | } else if (name == wasm.preloaded_strings.__wasm_call_ctors) { |
| 3011 | import.resolution = .__wasm_call_ctors; | 3008 | try wasm.resolveFunctionSynthetic(import, .__wasm_call_ctors, &.{}, &.{}); |
| 3012 | wasm.functions.putAssumeCapacity(.__wasm_call_ctors, {}); | | |
| 3013 | } else if (name == wasm.preloaded_strings.__wasm_init_tls) { | 3009 | } else if (name == wasm.preloaded_strings.__wasm_init_tls) { |
| 3014 | import.resolution = .__wasm_init_tls; | 3010 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_tls, &.{.i32}, &.{}); |
| 3015 | wasm.functions.putAssumeCapacity(.__wasm_init_tls, {}); | | |
| 3016 | } else { | 3011 | } else { |
| 3017 | try wasm.function_imports.put(gpa, name, .fromObject(func_index, wasm)); | 3012 | try wasm.function_imports.put(gpa, name, .fromObject(func_index, wasm)); |
| 3018 | } | 3013 | } |
| ... | @@ -3022,7 +3017,7 @@ fn markFunctionImport( | ... | @@ -3022,7 +3017,7 @@ fn markFunctionImport( |
| 3022 | } | 3017 | } |
| 3023 | | 3018 | |
| 3024 | /// Recursively mark alive everything referenced by the function. | 3019 | /// Recursively mark alive everything referenced by the function. |
| 3025 | fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) Allocator.Error!void { | 3020 | fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { |
| 3026 | const comp = wasm.base.comp; | 3021 | const comp = wasm.base.comp; |
| 3027 | const gpa = comp.gpa; | 3022 | const gpa = comp.gpa; |
| 3028 | const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i)); | 3023 | const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i)); |
| ... | @@ -3046,7 +3041,7 @@ fn markGlobalImport( | ... | @@ -3046,7 +3041,7 @@ fn markGlobalImport( |
| 3046 | name: String, | 3041 | name: String, |
| 3047 | import: *GlobalImport, | 3042 | import: *GlobalImport, |
| 3048 | global_index: GlobalImport.Index, | 3043 | global_index: GlobalImport.Index, |
| 3049 | ) !void { | 3044 | ) link.File.FlushError!void { |
| 3050 | if (import.flags.alive) return; | 3045 | if (import.flags.alive) return; |
| 3051 | import.flags.alive = true; | 3046 | import.flags.alive = true; |
| 3052 | | 3047 | |
| ... | @@ -3082,7 +3077,7 @@ fn markGlobalImport( | ... | @@ -3082,7 +3077,7 @@ fn markGlobalImport( |
| 3082 | } | 3077 | } |
| 3083 | } | 3078 | } |
| 3084 | | 3079 | |
| 3085 | fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex) Allocator.Error!void { | 3080 | fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex) link.File.FlushError!void { |
| 3086 | const comp = wasm.base.comp; | 3081 | const comp = wasm.base.comp; |
| 3087 | const gpa = comp.gpa; | 3082 | const gpa = comp.gpa; |
| 3088 | const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i)); | 3083 | const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i)); |
| ... | @@ -3105,7 +3100,7 @@ fn markTableImport( | ... | @@ -3105,7 +3100,7 @@ fn markTableImport( |
| 3105 | name: String, | 3100 | name: String, |
| 3106 | import: *TableImport, | 3101 | import: *TableImport, |
| 3107 | table_index: TableImport.Index, | 3102 | table_index: TableImport.Index, |
| 3108 | ) !void { | 3103 | ) link.File.FlushError!void { |
| 3109 | if (import.flags.alive) return; | 3104 | if (import.flags.alive) return; |
| 3110 | import.flags.alive = true; | 3105 | import.flags.alive = true; |
| 3111 | | 3106 | |
| ... | @@ -3127,7 +3122,7 @@ fn markTableImport( | ... | @@ -3127,7 +3122,7 @@ fn markTableImport( |
| 3127 | } | 3122 | } |
| 3128 | } | 3123 | } |
| 3129 | | 3124 | |
| 3130 | fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) Allocator.Error!void { | 3125 | fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.File.FlushError!void { |
| 3131 | const segment = segment_index.ptr(wasm); | 3126 | const segment = segment_index.ptr(wasm); |
| 3132 | if (segment.flags.alive) return; | 3127 | if (segment.flags.alive) return; |
| 3133 | segment.flags.alive = true; | 3128 | segment.flags.alive = true; |
| ... | @@ -3135,7 +3130,7 @@ fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) Allocato | ... | @@ -3135,7 +3130,7 @@ fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) Allocato |
| 3135 | try wasm.markRelocations(segment.relocations(wasm)); | 3130 | try wasm.markRelocations(segment.relocations(wasm)); |
| 3136 | } | 3131 | } |
| 3137 | | 3132 | |
| 3138 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) Allocator.Error!void { | 3133 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.File.FlushError!void { |
| 3139 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, *pointee, offset| { | 3134 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, *pointee, offset| { |
| 3140 | if (offset >= relocs.end) break; | 3135 | if (offset >= relocs.end) break; |
| 3141 | switch (tag) { | 3136 | switch (tag) { |
| ... | @@ -3751,7 +3746,7 @@ pub fn internValtypeList(wasm: *Wasm, valtype_list: []const std.wasm.Valtype) Al | ... | @@ -3751,7 +3746,7 @@ pub fn internValtypeList(wasm: *Wasm, valtype_list: []const std.wasm.Valtype) Al |
| 3751 | return .fromString(try internString(wasm, @ptrCast(valtype_list))); | 3746 | return .fromString(try internString(wasm, @ptrCast(valtype_list))); |
| 3752 | } | 3747 | } |
| 3753 | | 3748 | |
| 3754 | pub fn getExistingValtypeList(wasm: *Wasm, valtype_list: []const std.wasm.Valtype) ?ValtypeList { | 3749 | pub fn getExistingValtypeList(wasm: *const Wasm, valtype_list: []const std.wasm.Valtype) ?ValtypeList { |
| 3755 | return .fromString(getExistingString(wasm, @ptrCast(valtype_list)) orelse return null); | 3750 | return .fromString(getExistingString(wasm, @ptrCast(valtype_list)) orelse return null); |
| 3756 | } | 3751 | } |
| 3757 | | 3752 | |
| ... | @@ -3766,6 +3761,13 @@ pub fn getExistingFuncType(wasm: *const Wasm, ft: FunctionType) ?FunctionType.In | ... | @@ -3766,6 +3761,13 @@ pub fn getExistingFuncType(wasm: *const Wasm, ft: FunctionType) ?FunctionType.In |
| 3766 | return @enumFromInt(index); | 3761 | return @enumFromInt(index); |
| 3767 | } | 3762 | } |
| 3768 | | 3763 | |
| | 3764 | pub fn getExistingFuncType2(wasm: *const Wasm, params: []const std.wasm.Valtype, returns: []const std.wasm.Valtype) FunctionType.Index { |
| | 3765 | return getExistingFuncType(wasm, .{ |
| | 3766 | .params = getExistingValtypeList(wasm, params).?, |
| | 3767 | .returns = getExistingValtypeList(wasm, returns).?, |
| | 3768 | }).?; |
| | 3769 | } |
| | 3770 | |
| 3769 | pub fn internFunctionType( | 3771 | pub fn internFunctionType( |
| 3770 | wasm: *Wasm, | 3772 | wasm: *Wasm, |
| 3771 | cc: std.builtin.CallingConvention, | 3773 | cc: std.builtin.CallingConvention, |
| ... | @@ -4080,3 +4082,26 @@ fn addZcuImportReserved(wasm: *Wasm, nav_index: InternPool.Nav.Index) ZcuImportI | ... | @@ -4080,3 +4082,26 @@ fn addZcuImportReserved(wasm: *Wasm, nav_index: InternPool.Nav.Index) ZcuImportI |
| 4080 | gop.value_ptr.* = {}; | 4082 | gop.value_ptr.* = {}; |
| 4081 | return @enumFromInt(gop.index); | 4083 | return @enumFromInt(gop.index); |
| 4082 | } | 4084 | } |
| | 4085 | |
| | 4086 | fn resolveFunctionSynthetic( |
| | 4087 | wasm: *Wasm, |
| | 4088 | import: *FunctionImport, |
| | 4089 | res: FunctionImport.Resolution, |
| | 4090 | params: []const std.wasm.Valtype, |
| | 4091 | returns: []const std.wasm.Valtype, |
| | 4092 | ) link.File.FlushError!void { |
| | 4093 | import.resolution = res; |
| | 4094 | wasm.functions.putAssumeCapacity(res, {}); |
| | 4095 | // This is not only used for type-checking but also ensures the function |
| | 4096 | // type index is interned so that it is guaranteed to exist during `flush`. |
| | 4097 | const correct_func_type = try addFuncType(wasm, .{ |
| | 4098 | .params = try internValtypeList(wasm, params), |
| | 4099 | .returns = try internValtypeList(wasm, returns), |
| | 4100 | }); |
| | 4101 | if (import.type != correct_func_type) { |
| | 4102 | const diags = &wasm.base.comp.link_diags; |
| | 4103 | return import.source_location.fail(diags, "synthetic function {s} {} imported with incorrect signature {}", .{ |
| | 4104 | @tagName(res), correct_func_type.fmt(wasm), import.type.fmt(wasm), |
| | 4105 | }); |
| | 4106 | } |
| | 4107 | } |