mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
wasm-linker: refactor Limits and add flags
Rather than adding the flags "on-demand" during limits writing, we now properly parse them and store the flags within the limits itself. This also allows us to store whether we're using shared- memory or not. Only when the correct flag is set will we set the max within `Limits` or else we will leave it `undefined`.
This commit is contained in:
parent
b0024c4884
commit
09abd53da7
@ -551,8 +551,22 @@ test "Wasm - valtypes" {
|
||||
|
||||
/// Limits classify the size range of resizeable storage associated with memory types and table types.
|
||||
pub const Limits = struct {
|
||||
flags: u8,
|
||||
min: u32,
|
||||
max: ?u32,
|
||||
max: u32,
|
||||
|
||||
pub const Flags = enum(u8) {
|
||||
WASM_LIMITS_FLAG_HAS_MAX = 0x1,
|
||||
WASM_LIMITS_FLAG_IS_SHARED = 0x2,
|
||||
};
|
||||
|
||||
pub fn hasFlag(limits: Limits, flag: Flags) bool {
|
||||
return limits.flags & @enumToInt(flag) != 0;
|
||||
}
|
||||
|
||||
pub fn setFlag(limits: *Limits, flag: Flags) void {
|
||||
limits.flags |= @enumToInt(flag);
|
||||
}
|
||||
};
|
||||
|
||||
/// Initialization expressions are used to set the initial value on an object
|
||||
|
||||
@ -111,7 +111,11 @@ functions: std.AutoArrayHashMapUnmanaged(struct { file: ?u16, index: u32 }, std.
|
||||
/// Output global section
|
||||
wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{},
|
||||
/// Memory section
|
||||
memories: std.wasm.Memory = .{ .limits = .{ .min = 0, .max = null } },
|
||||
memories: std.wasm.Memory = .{ .limits = .{
|
||||
.min = 0,
|
||||
.max = undefined,
|
||||
.flags = 0,
|
||||
} },
|
||||
/// Output table section
|
||||
tables: std.ArrayListUnmanaged(std.wasm.Table) = .{},
|
||||
/// Output export section
|
||||
@ -396,7 +400,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
|
||||
const loc = try wasm_bin.createSyntheticSymbol("__indirect_function_table", .table);
|
||||
const symbol = loc.getSymbol(wasm_bin);
|
||||
const table: std.wasm.Table = .{
|
||||
.limits = .{ .min = 0, .max = null }, // will be overwritten during `mapFunctionTable`
|
||||
.limits = .{ .flags = 0, .min = 0, .max = undefined }, // will be overwritten during `mapFunctionTable`
|
||||
.reftype = .funcref,
|
||||
};
|
||||
if (options.output_mode == .Obj or options.import_table) {
|
||||
@ -1524,7 +1528,7 @@ fn mapFunctionTable(wasm: *Wasm) void {
|
||||
const sym_loc = wasm.findGlobalSymbol("__indirect_function_table").?;
|
||||
const symbol = sym_loc.getSymbol(wasm);
|
||||
const table = &wasm.tables.items[symbol.index - wasm.imported_tables_count];
|
||||
table.limits = .{ .min = index, .max = index };
|
||||
table.limits = .{ .min = index, .max = index, .flags = 0x1 };
|
||||
}
|
||||
}
|
||||
|
||||
@ -2236,8 +2240,9 @@ fn setupMemory(wasm: *Wasm) !void {
|
||||
if (mem.eql(u8, entry.key_ptr.*, ".tdata")) {
|
||||
if (wasm.findGlobalSymbol("__tls_base")) |loc| {
|
||||
const sym = loc.getSymbol(wasm);
|
||||
sym.index = try wasm.globals.append(wasm.base.allocator, wasm.imports.globalCount, .{
|
||||
.global_type = .{ .valtype = .i32_const, .mutable = false },
|
||||
sym.index = @intCast(u32, wasm.wasm_globals.items.len) + wasm.imported_globals_count;
|
||||
try wasm.wasm_globals.append(wasm.base.allocator, .{
|
||||
.global_type = .{ .valtype = .i32, .mutable = false },
|
||||
.init = .{ .i32_const = @intCast(i32, memory_ptr) },
|
||||
});
|
||||
}
|
||||
@ -2305,6 +2310,10 @@ fn setupMemory(wasm: *Wasm) !void {
|
||||
return error.MemoryTooBig;
|
||||
}
|
||||
wasm.memories.limits.max = @intCast(u32, max_memory / page_size);
|
||||
wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX);
|
||||
if (wasm.base.options.shared_memory) {
|
||||
wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED);
|
||||
}
|
||||
log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max});
|
||||
}
|
||||
}
|
||||
@ -3517,10 +3526,10 @@ fn emitNameSubsection(wasm: *Wasm, section_id: std.wasm.NameSubsection, names: a
|
||||
}
|
||||
|
||||
fn emitLimits(writer: anytype, limits: std.wasm.Limits) !void {
|
||||
try leb.writeULEB128(writer, @boolToInt(limits.max != null));
|
||||
try writer.writeByte(limits.flags);
|
||||
try leb.writeULEB128(writer, limits.min);
|
||||
if (limits.max) |max| {
|
||||
try leb.writeULEB128(writer, max);
|
||||
if (limits.hasFlag(.WASM_LIMITS_FLAG_HAS_MAX)) {
|
||||
try leb.writeULEB128(writer, limits.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -852,12 +852,17 @@ fn readEnum(comptime T: type, reader: anytype) !T {
|
||||
}
|
||||
|
||||
fn readLimits(reader: anytype) !std.wasm.Limits {
|
||||
const flags = try readLeb(u1, reader);
|
||||
const flags = try reader.readByte();
|
||||
const min = try readLeb(u32, reader);
|
||||
return std.wasm.Limits{
|
||||
var limits: std.wasm.Limits = .{
|
||||
.flags = flags,
|
||||
.min = min,
|
||||
.max = if (flags == 0) null else try readLeb(u32, reader),
|
||||
.max = undefined,
|
||||
};
|
||||
if (limits.hasFlag(.WASM_LIMITS_FLAG_HAS_MAX)) {
|
||||
limits.max = try readLeb(u32, reader);
|
||||
}
|
||||
return limits;
|
||||
}
|
||||
|
||||
fn readInit(reader: anytype) !std.wasm.InitExpression {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user