authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 19:08:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 19:08:41-04:00
log614cab5d68176ea56e48195d04997738297429a1
tree7d430331b69291937b2c58918999ef5fde4f3df1
parentda56959a9a7dd7b83a8d2bc6b1454ae546a48be6
signaturelock-open Commit is signed but in an unrecognized format.

fix passing string literals to async functions


3 files changed, 32 insertions(+), 6 deletions(-)

src/all_types.hpp+1
...@@ -3763,6 +3763,7 @@ struct FnWalkAttrs {...@@ -3763,6 +3763,7 @@ struct FnWalkAttrs {
37633763
3764struct FnWalkCall {3764struct FnWalkCall {
3765 ZigList<LLVMValueRef> *gen_param_values;3765 ZigList<LLVMValueRef> *gen_param_values;
3766 ZigList<ZigType *> *gen_param_types;
3766 IrInstructionCallGen *inst;3767 IrInstructionCallGen *inst;
3767 bool is_var_args;3768 bool is_var_args;
3768};3769};
src/codegen.cpp+10-6
...@@ -1575,14 +1575,14 @@ static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) {...@@ -1575,14 +1575,14 @@ static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) {
1575 }1575 }
1576}1576}
15771577
1578static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,1578static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,
1579 LLVMValueRef value)1579 LLVMValueRef value)
1580{1580{
1581 assert(ptr_type->id == ZigTypeIdPointer);1581 assert(ptr_type->id == ZigTypeIdPointer);
1582 ZigType *child_type = ptr_type->data.pointer.child_type;1582 ZigType *child_type = ptr_type->data.pointer.child_type;
15831583
1584 if (!type_has_bits(child_type))1584 if (!type_has_bits(child_type))
1585 return nullptr;1585 return;
15861586
1587 if (handle_is_ptr(child_type)) {1587 if (handle_is_ptr(child_type)) {
1588 assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind);1588 assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind);
...@@ -1602,13 +1602,13 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty...@@ -1602,13 +1602,13 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
1602 ZigLLVMBuildMemCpy(g->builder, dest_ptr, align_bytes, src_ptr, align_bytes,1602 ZigLLVMBuildMemCpy(g->builder, dest_ptr, align_bytes, src_ptr, align_bytes,
1603 LLVMConstInt(usize->llvm_type, size_bytes, false),1603 LLVMConstInt(usize->llvm_type, size_bytes, false),
1604 ptr_type->data.pointer.is_volatile);1604 ptr_type->data.pointer.is_volatile);
1605 return nullptr;1605 return;
1606 }1606 }
16071607
1608 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;1608 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
1609 if (host_int_bytes == 0) {1609 if (host_int_bytes == 0) {
1610 gen_store(g, value, ptr, ptr_type);1610 gen_store(g, value, ptr, ptr_type);
1611 return nullptr;1611 return;
1612 }1612 }
16131613
1614 bool big_endian = g->is_big_endian;1614 bool big_endian = g->is_big_endian;
...@@ -1638,7 +1638,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty...@@ -1638,7 +1638,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
1638 LLVMValueRef ored_value = LLVMBuildOr(g->builder, shifted_value, anded_containing_int, "");1638 LLVMValueRef ored_value = LLVMBuildOr(g->builder, shifted_value, anded_containing_int, "");
16391639
1640 gen_store(g, ored_value, ptr, ptr_type);1640 gen_store(g, ored_value, ptr, ptr_type);
1641 return nullptr;1641 return;
1642}1642}
16431643
1644static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {1644static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
...@@ -1958,6 +1958,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -1958,6 +1958,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
1958 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);1958 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
1959 assert(param_value);1959 assert(param_value);
1960 fn_walk->data.call.gen_param_values->append(param_value);1960 fn_walk->data.call.gen_param_values->append(param_value);
1961 fn_walk->data.call.gen_param_types->append(param_type);
1961 }1962 }
1962 }1963 }
1963 return;1964 return;
...@@ -3821,6 +3822,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3821,6 +3822,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3821 bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type);3822 bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type);
3822 bool is_var_args = fn_type_id->is_var_args;3823 bool is_var_args = fn_type_id->is_var_args;
3823 ZigList<LLVMValueRef> gen_param_values = {};3824 ZigList<LLVMValueRef> gen_param_values = {};
3825 ZigList<ZigType *> gen_param_types = {};
3824 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;3826 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
3825 LLVMValueRef zero = LLVMConstNull(usize_type_ref);3827 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
3826 LLVMValueRef frame_result_loc;3828 LLVMValueRef frame_result_loc;
...@@ -3923,6 +3925,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3923,6 +3925,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3923 fn_walk.data.call.inst = instruction;3925 fn_walk.data.call.inst = instruction;
3924 fn_walk.data.call.is_var_args = is_var_args;3926 fn_walk.data.call.is_var_args = is_var_args;
3925 fn_walk.data.call.gen_param_values = &gen_param_values;3927 fn_walk.data.call.gen_param_values = &gen_param_values;
3928 fn_walk.data.call.gen_param_types = &gen_param_types;
3926 walk_function_params(g, fn_type, &fn_walk);3929 walk_function_params(g, fn_type, &fn_walk);
39273930
3928 ZigLLVM_FnInline fn_inline;3931 ZigLLVM_FnInline fn_inline;
...@@ -3964,7 +3967,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3964,7 +3967,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
39643967
3965 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {3968 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
3966 LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, casted_frame, arg_start_i + arg_i, "");3969 LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, casted_frame, arg_start_i + arg_i, "");
3967 LLVMBuildStore(g->builder, gen_param_values.at(arg_i), arg_ptr);3970 gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true),
3971 gen_param_values.at(arg_i));
3968 }3972 }
3969 }3973 }
3970 if (instruction->is_async) {3974 if (instruction->is_async) {
test/stage1/behavior/coroutines.zig+21
...@@ -568,3 +568,24 @@ test "errdefers in scope get run when canceling async fn call" {...@@ -568,3 +568,24 @@ test "errdefers in scope get run when canceling async fn call" {
568 };568 };
569 S.doTheTest();569 S.doTheTest();
570}570}
571
572test "pass string literal to async function" {
573 const S = struct {
574 var frame: anyframe = undefined;
575 var ok: bool = false;
576
577 fn doTheTest() void {
578 _ = async hello("hello");
579 resume frame;
580 expect(ok);
581 }
582
583 fn hello(msg: []const u8) void {
584 frame = @frame();
585 suspend;
586 expectEqual(([]const u8)("hello"), msg);
587 ok = true;
588 }
589 };
590 S.doTheTest();
591}