| ... | ... | @@ -75,6 +75,13 @@ pub const FunctionImport = struct { |
| 75 | 75 | function_index: ScratchSpace.FuncTypeIndex, |
| 76 | 76 | }; |
| 77 | 77 | |
| 78 | pub const GlobalImport = struct { |
| 79 | module_name: Wasm.String, |
| 80 | name: Wasm.String, |
| 81 | valtype: std.wasm.Valtype, |
| 82 | mutable: bool, |
| 83 | }; |
| 84 | |
| 78 | 85 | pub const DataSegmentFlags = enum(u32) { active, passive, active_memidx }; |
| 79 | 86 | |
| 80 | 87 | pub const SubsectionType = enum(u8) { |
| ... | ... | @@ -105,7 +112,7 @@ pub const Symbol = struct { |
| 105 | 112 | data: Wasm.ObjectData.Index, |
| 106 | 113 | data_import: void, |
| 107 | 114 | global: Wasm.ObjectGlobalIndex, |
| 108 | | global_import: Wasm.GlobalImport.Index, |
| 115 | global_import: ScratchSpace.GlobalImportIndex, |
| 109 | 116 | section: Wasm.ObjectSectionIndex, |
| 110 | 117 | table: Wasm.ObjectTableIndex, |
| 111 | 118 | table_import: Wasm.TableImport.Index, |
| ... | ... | @@ -116,6 +123,7 @@ pub const ScratchSpace = struct { |
| 116 | 123 | func_types: std.ArrayListUnmanaged(Wasm.FunctionType.Index) = .empty, |
| 117 | 124 | func_type_indexes: std.ArrayListUnmanaged(FuncTypeIndex) = .empty, |
| 118 | 125 | func_imports: std.ArrayListUnmanaged(FunctionImport) = .empty, |
| 126 | global_imports: std.ArrayListUnmanaged(GlobalImport) = .empty, |
| 119 | 127 | symbol_table: std.ArrayListUnmanaged(Symbol) = .empty, |
| 120 | 128 | segment_info: std.ArrayListUnmanaged(SegmentInfo) = .empty, |
| 121 | 129 | exports: std.ArrayListUnmanaged(Export) = .empty, |
| ... | ... | @@ -141,6 +149,15 @@ pub const ScratchSpace = struct { |
| 141 | 149 | } |
| 142 | 150 | }; |
| 143 | 151 | |
| 152 | /// Index into `global_imports`. |
| 153 | const GlobalImportIndex = enum(u32) { |
| 154 | _, |
| 155 | |
| 156 | fn ptr(index: GlobalImportIndex, ss: *const ScratchSpace) *GlobalImport { |
| 157 | return &ss.global_imports.items[@intFromEnum(index)]; |
| 158 | } |
| 159 | }; |
| 160 | |
| 144 | 161 | /// Index into `func_types`. |
| 145 | 162 | const FuncTypeIndex = enum(u32) { |
| 146 | 163 | _, |
| ... | ... | @@ -155,6 +172,7 @@ pub const ScratchSpace = struct { |
| 155 | 172 | ss.func_types.deinit(gpa); |
| 156 | 173 | ss.func_type_indexes.deinit(gpa); |
| 157 | 174 | ss.func_imports.deinit(gpa); |
| 175 | ss.global_imports.deinit(gpa); |
| 158 | 176 | ss.symbol_table.deinit(gpa); |
| 159 | 177 | ss.segment_info.deinit(gpa); |
| 160 | 178 | ss.* = undefined; |
| ... | ... | @@ -165,6 +183,7 @@ pub const ScratchSpace = struct { |
| 165 | 183 | ss.func_types.clearRetainingCapacity(); |
| 166 | 184 | ss.func_type_indexes.clearRetainingCapacity(); |
| 167 | 185 | ss.func_imports.clearRetainingCapacity(); |
| 186 | ss.global_imports.clearRetainingCapacity(); |
| 168 | 187 | ss.symbol_table.clearRetainingCapacity(); |
| 169 | 188 | ss.segment_info.clearRetainingCapacity(); |
| 170 | 189 | } |
| ... | ... | @@ -361,7 +380,7 @@ pub fn parse( |
| 361 | 380 | symbol.name = function_import.ptr(ss).name.toOptional(); |
| 362 | 381 | } |
| 363 | 382 | } else { |
| 364 | | symbol.pointee = .{ .function = @enumFromInt(functions_start + local_index) }; |
| 383 | symbol.pointee = .{ .function = @enumFromInt(functions_start + (local_index - ss.func_imports.items.len)) }; |
| 365 | 384 | const name, pos = readBytes(bytes, pos); |
| 366 | 385 | symbol.name = (try wasm.internString(name)).toOptional(); |
| 367 | 386 | } |
| ... | ... | @@ -369,16 +388,16 @@ pub fn parse( |
| 369 | 388 | .global => { |
| 370 | 389 | const local_index, pos = readLeb(u32, bytes, pos); |
| 371 | 390 | if (symbol.flags.undefined) { |
| 372 | | const global_import: Wasm.GlobalImport.Index = @enumFromInt(global_imports_start + local_index); |
| 391 | const global_import: ScratchSpace.GlobalImportIndex = @enumFromInt(local_index); |
| 373 | 392 | symbol.pointee = .{ .global_import = global_import }; |
| 374 | 393 | if (symbol.flags.explicit_name) { |
| 375 | 394 | const name, pos = readBytes(bytes, pos); |
| 376 | 395 | symbol.name = (try wasm.internString(name)).toOptional(); |
| 377 | 396 | } else { |
| 378 | | symbol.name = global_import.key(wasm).toOptional(); |
| 397 | symbol.name = global_import.ptr(ss).name.toOptional(); |
| 379 | 398 | } |
| 380 | 399 | } else { |
| 381 | | symbol.pointee = .{ .global = @enumFromInt(globals_start + local_index) }; |
| 400 | symbol.pointee = .{ .global = @enumFromInt(globals_start + (local_index - ss.global_imports.items.len)) }; |
| 382 | 401 | const name, pos = readBytes(bytes, pos); |
| 383 | 402 | symbol.name = (try wasm.internString(name)).toOptional(); |
| 384 | 403 | } |
| ... | ... | @@ -579,16 +598,11 @@ pub fn parse( |
| 579 | 598 | const valtype, pos = readEnum(std.wasm.Valtype, bytes, pos); |
| 580 | 599 | const mutable = bytes[pos] == 0x01; |
| 581 | 600 | pos += 1; |
| 582 | | try wasm.object_global_imports.put(gpa, interned_name, .{ |
| 583 | | .flags = .{ |
| 584 | | .global_type = .{ |
| 585 | | .valtype = .from(valtype), |
| 586 | | .mutable = mutable, |
| 587 | | }, |
| 588 | | }, |
| 589 | | .module_name = interned_module_name.toOptional(), |
| 590 | | .source_location = source_location, |
| 591 | | .resolution = .unresolved, |
| 601 | try ss.global_imports.append(gpa, .{ |
| 602 | .name = interned_name, |
| 603 | .valtype = valtype, |
| 604 | .mutable = mutable, |
| 605 | .module_name = interned_module_name, |
| 592 | 606 | }); |
| 593 | 607 | }, |
| 594 | 608 | .table => { |
| ... | ... | @@ -840,6 +854,61 @@ pub fn parse( |
| 840 | 854 | }; |
| 841 | 855 | } |
| 842 | 856 | }, |
| 857 | .global_import => |index| { |
| 858 | const ptr = index.ptr(ss); |
| 859 | const name = symbol.name.unwrap().?; |
| 860 | if (symbol.flags.binding == .local) { |
| 861 | diags.addParseError(path, "local symbol '{s}' references import", .{name.slice(wasm)}); |
| 862 | continue; |
| 863 | } |
| 864 | const gop = try wasm.object_global_imports.getOrPut(gpa, name); |
| 865 | if (gop.found_existing) { |
| 866 | const existing_ty = gop.value_ptr.flags.global_type.to(); |
| 867 | if (ptr.valtype != existing_ty.valtype) { |
| 868 | var err = try diags.addErrorWithNotes(2); |
| 869 | try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)}); |
| 870 | gop.value_ptr.source_location.addNote(wasm, &err, "type {s} here", .{@tagName(existing_ty.valtype)}); |
| 871 | source_location.addNote(wasm, &err, "type {s} here", .{@tagName(ptr.valtype)}); |
| 872 | continue; |
| 873 | } |
| 874 | if (ptr.mutable != existing_ty.mutable) { |
| 875 | var err = try diags.addErrorWithNotes(2); |
| 876 | try err.addMsg("symbol '{s}' mismatching global mutability", .{name.slice(wasm)}); |
| 877 | gop.value_ptr.source_location.addNote(wasm, &err, "{s} here", .{ |
| 878 | if (existing_ty.mutable) "mutable" else "not mutable", |
| 879 | }); |
| 880 | source_location.addNote(wasm, &err, "{s} here", .{ |
| 881 | if (ptr.mutable) "mutable" else "not mutable", |
| 882 | }); |
| 883 | continue; |
| 884 | } |
| 885 | if (gop.value_ptr.module_name != ptr.module_name.toOptional()) { |
| 886 | var err = try diags.addErrorWithNotes(2); |
| 887 | try err.addMsg("function symbol '{s}' mismatching module names", .{name.slice(wasm)}); |
| 888 | if (gop.value_ptr.module_name.slice(wasm)) |module_name| { |
| 889 | gop.value_ptr.source_location.addNote(wasm, &err, "module '{s}' here", .{module_name}); |
| 890 | } else { |
| 891 | gop.value_ptr.source_location.addNote(wasm, &err, "no module here", .{}); |
| 892 | } |
| 893 | source_location.addNote(wasm, &err, "module '{s}' here", .{ptr.module_name.slice(wasm)}); |
| 894 | continue; |
| 895 | } |
| 896 | if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong; |
| 897 | if (!symbol.flags.visibility_hidden) gop.value_ptr.flags.visibility_hidden = false; |
| 898 | if (symbol.flags.no_strip) gop.value_ptr.flags.no_strip = true; |
| 899 | } else { |
| 900 | gop.value_ptr.* = .{ |
| 901 | .flags = symbol.flags, |
| 902 | .module_name = ptr.module_name.toOptional(), |
| 903 | .source_location = source_location, |
| 904 | .resolution = .unresolved, |
| 905 | }; |
| 906 | gop.value_ptr.flags.global_type = .{ |
| 907 | .valtype = .from(ptr.valtype), |
| 908 | .mutable = ptr.mutable, |
| 909 | }; |
| 910 | } |
| 911 | }, |
| 843 | 912 | .function => |index| { |
| 844 | 913 | assert(!symbol.flags.undefined); |
| 845 | 914 | const ptr = index.ptr(wasm); |
| ... | ... | @@ -882,7 +951,7 @@ pub fn parse( |
| 882 | 951 | } |
| 883 | 952 | }, |
| 884 | 953 | |
| 885 | | inline .global_import, .table_import => |i| { |
| 954 | .table_import => |i| { |
| 886 | 955 | const ptr = i.value(wasm); |
| 887 | 956 | assert(i.key(wasm).toOptional() == symbol.name); // TODO |
| 888 | 957 | ptr.flags = symbol.flags; |