mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
wasm: Implement @ptrToInt and fix indirect function call
- Previously the table index and function type index were switched. This commit swaps them. - This also emits the correct indirect function calls count when importing the function table
This commit is contained in:
parent
f644c8b047
commit
b9a0401e23
@ -1200,6 +1200,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.optional_payload => self.airOptionalPayload(inst),
|
||||
.optional_payload_ptr => self.airOptionalPayload(inst),
|
||||
.optional_payload_ptr_set => self.airOptionalPayloadPtrSet(inst),
|
||||
.ptrtoint => self.airPtrToInt(inst),
|
||||
.ret => self.airRet(inst),
|
||||
.ret_ptr => self.airRetPtr(inst),
|
||||
.ret_load => self.airRetLoad(inst),
|
||||
@ -1729,6 +1730,8 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
|
||||
} else {
|
||||
try self.addLabel(.memory_address, decl.link.wasm.sym_index);
|
||||
}
|
||||
} else if (val.castTag(.int_u64)) |int_ptr| {
|
||||
try self.addImm32(@bitCast(i32, @intCast(u32, int_ptr.data)));
|
||||
} else return self.fail("Wasm TODO: emitConstant for other const pointer tag {s}", .{val.tag()});
|
||||
},
|
||||
.Void => {},
|
||||
@ -2601,3 +2604,9 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
|
||||
return slice_local;
|
||||
}
|
||||
|
||||
fn airPtrToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
|
||||
const un_op = self.air.instructions.items(.data)[inst].un_op;
|
||||
return self.resolveInst(un_op);
|
||||
}
|
||||
|
@ -284,10 +284,12 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const label = emit.mir.instructions.items(.data)[inst].label;
|
||||
const type_index = emit.mir.instructions.items(.data)[inst].label;
|
||||
try emit.code.append(std.wasm.opcode(.call_indirect));
|
||||
// NOTE: If we remove unused function types in the future for incremental
|
||||
// linking, we must also emit a relocation for this `type_index`
|
||||
try leb128.writeULEB128(emit.code.writer(), type_index);
|
||||
try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index
|
||||
try leb128.writeULEB128(emit.code.writer(), label);
|
||||
}
|
||||
|
||||
fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
|
@ -646,7 +646,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
|
||||
.kind = .{
|
||||
.table = .{
|
||||
.limits = .{
|
||||
.min = @intCast(u32, self.imports.count()),
|
||||
.min = @intCast(u32, self.function_table.count()),
|
||||
.max = null,
|
||||
},
|
||||
.reftype = .funcref,
|
||||
@ -678,7 +678,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
|
||||
header_offset,
|
||||
.import,
|
||||
@intCast(u32, (try file.getPos()) - header_offset - header_size),
|
||||
@intCast(u32, self.imports.count() + @boolToInt(import_memory)),
|
||||
@intCast(u32, self.imports.count() + @boolToInt(import_memory) + @boolToInt(import_table)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,15 @@ test {
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
_ = @import("behavior/error.zig");
|
||||
_ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
_ = @import("behavior/hasdecl.zig");
|
||||
_ = @import("behavior/hasfield.zig");
|
||||
_ = @import("behavior/import.zig");
|
||||
_ = @import("behavior/incomplete_struct_param_tld.zig");
|
||||
_ = @import("behavior/inttoptr.zig");
|
||||
_ = @import("behavior/ptrcast.zig");
|
||||
_ = @import("behavior/pub_enum.zig");
|
||||
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("behavior/slice_sentinel_comptime.zig");
|
||||
_ = @import("behavior/truncate.zig");
|
||||
_ = @import("behavior/type.zig");
|
||||
@ -57,19 +62,14 @@ test {
|
||||
_ = @import("behavior/for.zig");
|
||||
_ = @import("behavior/generics.zig");
|
||||
_ = @import("behavior/if.zig");
|
||||
_ = @import("behavior/incomplete_struct_param_tld.zig");
|
||||
_ = @import("behavior/int128.zig");
|
||||
_ = @import("behavior/inttoptr.zig");
|
||||
_ = @import("behavior/member_func.zig");
|
||||
_ = @import("behavior/null.zig");
|
||||
_ = @import("behavior/optional.zig");
|
||||
_ = @import("behavior/pointers.zig");
|
||||
_ = @import("behavior/ptrcast.zig");
|
||||
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("behavior/struct.zig");
|
||||
_ = @import("behavior/this.zig");
|
||||
_ = @import("behavior/translate_c_macros.zig");
|
||||
_ = @import("behavior/underscore.zig");
|
||||
_ = @import("behavior/while.zig");
|
||||
_ = @import("behavior/void.zig");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user