diff --git a/src/ir.cpp b/src/ir.cpp index 20a21bb5c3..5fc31db3ef 100644 --- a/src/ir.cpp +++ b/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); diff --git a/std/event/loop.zig b/std/event/loop.zig index 70cd8d2ab6..f0ae67a3d1 100644 --- a/std/event/loop.zig +++ b/std/event/loop.zig @@ -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();