mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 16:24:51 +00:00
fix var args call on non-generic function
This commit is contained in:
parent
cfe84423c9
commit
93840f8610
66
src/ir.cpp
66
src/ir.cpp
@ -15799,26 +15799,60 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
}
|
||||
size_t iter_count = (call_param_count < call_instruction->arg_count) ?
|
||||
call_param_count : call_instruction->arg_count;
|
||||
for (size_t call_i = 0; call_i < iter_count; call_i += 1) {
|
||||
for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) {
|
||||
IrInstruction *old_arg = call_instruction->args[call_i]->child;
|
||||
if (type_is_invalid(old_arg->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
casted_arg = old_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
if (old_arg->value.type->id == ZigTypeIdArgTuple) {
|
||||
for (size_t arg_tuple_i = old_arg->value.data.x_arg_tuple.start_index;
|
||||
arg_tuple_i < old_arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1)
|
||||
{
|
||||
ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
|
||||
if (arg_var == nullptr) {
|
||||
ir_add_error(ira, old_arg,
|
||||
buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, old_arg, arg_var);
|
||||
if (type_is_invalid(arg_var_ptr_inst->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *arg_tuple_arg = ir_get_deref(ira, old_arg, arg_var_ptr_inst, nullptr);
|
||||
if (type_is_invalid(arg_tuple_arg->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, arg_tuple_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
casted_arg = arg_tuple_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
}
|
||||
} else {
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
casted_arg = old_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(next_arg_index == call_param_count);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const std = @import("../std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const root = @import("root");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
@ -85,6 +86,18 @@ pub const Loop = struct {
|
||||
};
|
||||
};
|
||||
|
||||
pub const IoMode = enum {
|
||||
blocking,
|
||||
evented,
|
||||
};
|
||||
pub const io_mode: IoMode = if (@hasDecl(root, "io_mode")) root.io_mode else IoMode.blocking;
|
||||
var global_instance_state: Loop = undefined;
|
||||
const default_instance: ?*Loop = switch (io_mode) {
|
||||
.blocking => null,
|
||||
.evented => &global_instance_state,
|
||||
};
|
||||
pub const instance: ?*Loop = if (@hasDecl(root, "event_loop")) root.event_loop else default_instance;
|
||||
|
||||
/// After initialization, call run().
|
||||
/// TODO copy elision / named return values so that the threads referencing *Loop
|
||||
/// have the correct pointer value.
|
||||
@ -599,7 +612,7 @@ pub const Loop = struct {
|
||||
/// If the build is multi-threaded and there is an event loop, then it calls `yield`. Otherwise,
|
||||
/// does nothing.
|
||||
pub fn startCpuBoundOperation() void {
|
||||
if (builtin.is_single_threaded) {
|
||||
if (builtin.single_threaded) {
|
||||
return;
|
||||
} else if (instance) |event_loop| {
|
||||
event_loop.yield();
|
||||
@ -881,7 +894,7 @@ test "std.event.Loop - call" {
|
||||
|
||||
var did_it = false;
|
||||
const handle = async Loop.call(testEventLoop);
|
||||
const handle2 = async Loop.call(testEventLoop2, handle, &did_it);
|
||||
const handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
|
||||
|
||||
loop.run();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user