Commit 1544625df3
Changed files (3)
src
link
src/link/Wasm/Archive.zig
@@ -218,6 +218,7 @@ pub fn parseObject(archive: Archive, allocator: Allocator, file_offset: u32) !Ob
const object_file = try std.fs.cwd().openFile(archive.name, .{});
errdefer object_file.close();
+ const object_file_size = try header.size();
try object_file.seekTo(current_offset);
- return Object.create(allocator, object_file, name);
+ return Object.create(allocator, object_file, name, object_file_size);
}
src/link/Wasm/Object.zig
@@ -105,14 +105,33 @@ pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadErro
/// Initializes a new `Object` from a wasm object file.
/// This also parses and verifies the object file.
-pub fn create(gpa: Allocator, file: std.fs.File, name: []const u8) InitError!Object {
+/// When a max size is given, will only parse up to the given size,
+/// else will read until the end of the file.
+pub fn create(gpa: Allocator, file: std.fs.File, name: []const u8, maybe_max_size: ?usize) InitError!Object {
var object: Object = .{
.file = file,
.name = try gpa.dupe(u8, name),
};
var is_object_file: bool = false;
- try object.parse(gpa, file.reader(), &is_object_file);
+ const size = maybe_max_size orelse size: {
+ errdefer gpa.free(object.name);
+ const stat = try file.stat();
+ break :size @intCast(usize, stat.size);
+ };
+
+ const file_contents = try gpa.alloc(u8, size);
+ defer gpa.free(file_contents);
+ var file_reader = file.reader();
+ var read: usize = 0;
+ while (read < size) {
+ const n = try file_reader.read(file_contents[read..]);
+ std.debug.assert(n != 0);
+ read += n;
+ }
+ var fbs = std.io.fixedBufferStream(file_contents);
+
+ try object.parse(gpa, fbs.reader(), &is_object_file);
errdefer object.deinit(gpa);
if (!is_object_file) return error.NotObjectFile;
src/link/Wasm.zig
@@ -378,7 +378,7 @@ fn parseObjectFile(self: *Wasm, path: []const u8) !bool {
const file = try fs.cwd().openFile(path, .{});
errdefer file.close();
- var object = Object.create(self.base.allocator, file, path) catch |err| switch (err) {
+ var object = Object.create(self.base.allocator, file, path, null) catch |err| switch (err) {
error.InvalidMagicByte, error.NotObjectFile => return false,
else => |e| return e,
};
@@ -595,8 +595,8 @@ fn resolveSymbolsInArchives(self: *Wasm) !void {
// Parse object and and resolve symbols again before we check remaining
// undefined symbols.
const object_file_index = @intCast(u16, self.objects.items.len);
- const object = try self.objects.addOne(self.base.allocator);
- object.* = try archive.parseObject(self.base.allocator, offset.items[0]);
+ var object = try archive.parseObject(self.base.allocator, offset.items[0]);
+ try self.objects.append(self.base.allocator, object);
try self.resolveSymbolsInObject(object_file_index);
// continue loop for any remaining undefined symbols that still exist
@@ -860,7 +860,8 @@ fn getGlobalType(self: *const Wasm, loc: SymbolLoc) wasm.GlobalType {
if (is_undefined) {
return obj.findImport(.global, symbol.index).kind.global;
}
- return obj.globals[symbol.index].global_type;
+ const import_global_count = obj.importedCountByKind(.global);
+ return obj.globals[symbol.index - import_global_count].global_type;
}
if (is_undefined) {
return self.imports.get(loc).?.kind.global;
@@ -880,7 +881,9 @@ fn getFunctionSignature(self: *const Wasm, loc: SymbolLoc) wasm.Type {
const ty_index = obj.findImport(.function, symbol.index).kind.function;
return obj.func_types[ty_index];
}
- return obj.func_types[obj.functions[symbol.index].type_index];
+ const import_function_count = obj.importedCountByKind(.function);
+ const type_index = obj.functions[symbol.index - import_function_count].type_index;
+ return obj.func_types[type_index];
}
if (is_undefined) {
const ty_index = self.imports.get(loc).?.kind.function;