authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-28 21:48:20-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-28 21:48:20-05:00
logc6227661568a9e8cad9d28bd7a11cb76c4f9c1c1
tree2e6278b864ccfd8b10004913b2d8098f813d3be6
parent807a5e94e976f03058426e04dceef449a5bf7ed8

async function fulfills promise atomically


2 files changed, 33 insertions(+), 8 deletions(-)

src/codegen.cpp+14-3
...@@ -4132,8 +4132,9 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,...@@ -4132,8 +4132,9 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
4132 IrInstructionAtomicRmw *instruction)4132 IrInstructionAtomicRmw *instruction)
4133{4133{
4134 bool is_signed;4134 bool is_signed;
4135 if (instruction->operand->value.type->id == TypeTableEntryIdInt) {4135 TypeTableEntry *operand_type = instruction->operand->value.type;
4136 is_signed = instruction->operand->value.type->data.integral.is_signed;4136 if (operand_type->id == TypeTableEntryIdInt) {
4137 is_signed = operand_type->data.integral.is_signed;
4137 } else {4138 } else {
4138 is_signed = false;4139 is_signed = false;
4139 }4140 }
...@@ -4141,7 +4142,17 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,...@@ -4141,7 +4142,17 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
4141 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);4142 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
4142 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);4143 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
4143 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);4144 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
4144 return LLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, false);4145
4146 if (get_codegen_ptr_type(operand_type) == nullptr) {
4147 return LLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, false);
4148 }
4149
4150 // it's a pointer but we need to treat it as an int
4151 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,
4152 LLVMPointerType(g->builtin_types.entry_usize->type_ref, 0), "");
4153 LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_usize->type_ref, "");
4154 LLVMValueRef uncasted_result = LLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, false);
4155 return LLVMBuildIntToPtr(g->builder, uncasted_result, operand_type->type_ref, "");
4145}4156}
41464157
4147static void set_debug_location(CodeGen *g, IrInstruction *instruction) {4158static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
src/ir.cpp+19-5
...@@ -2727,7 +2727,13 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode...@@ -2727,7 +2727,13 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
2727 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);2727 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
2728 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);2728 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2729 }2729 }
2730 IrInstruction *maybe_await_handle = ir_build_load_ptr(irb, scope, node, irb->exec->coro_awaiter_field_ptr);2730 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
2731 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
2732 // TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig
2733 IrInstruction *replacement_value = irb->exec->coro_handle;
2734 IrInstruction *maybe_await_handle = ir_build_atomic_rmw(irb, scope, node,
2735 promise_type_val, irb->exec->coro_awaiter_field_ptr, nullptr, replacement_value, nullptr,
2736 AtomicRmwOp_xchg, AtomicOrderSeqCst);
2731 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_await_handle);2737 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_await_handle);
2732 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false);2738 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false);
2733 return ir_build_cond_br(irb, scope, node, is_non_null, irb->exec->coro_normal_final, irb->exec->coro_early_final,2739 return ir_build_cond_br(irb, scope, node, is_non_null, irb->exec->coro_normal_final, irb->exec->coro_early_final,
...@@ -17433,8 +17439,12 @@ static TypeTableEntry *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstr...@@ -17433,8 +17439,12 @@ static TypeTableEntry *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstr
17433 return ira->codegen->builtin_types.entry_invalid;17439 return ira->codegen->builtin_types.entry_invalid;
1743417440
17435 AtomicRmwOp op;17441 AtomicRmwOp op;
17436 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->other, &op)) {17442 if (instruction->op == nullptr) {
17437 return ira->codegen->builtin_types.entry_invalid;17443 op = instruction->resolved_op;
17444 } else {
17445 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->other, &op)) {
17446 return ira->codegen->builtin_types.entry_invalid;
17447 }
17438 }17448 }
1743917449
17440 IrInstruction *operand = instruction->operand->other;17450 IrInstruction *operand = instruction->operand->other;
...@@ -17446,8 +17456,12 @@ static TypeTableEntry *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstr...@@ -17446,8 +17456,12 @@ static TypeTableEntry *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstr
17446 return ira->codegen->builtin_types.entry_invalid;17456 return ira->codegen->builtin_types.entry_invalid;
1744717457
17448 AtomicOrder ordering;17458 AtomicOrder ordering;
17449 if (!ir_resolve_atomic_order(ira, instruction->ordering->other, &ordering))17459 if (instruction->ordering == nullptr) {
17450 return ira->codegen->builtin_types.entry_invalid;17460 ordering = instruction->resolved_ordering;
17461 } else {
17462 if (!ir_resolve_atomic_order(ira, instruction->ordering->other, &ordering))
17463 return ira->codegen->builtin_types.entry_invalid;
17464 }
1745117465
17452 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)17466 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
17453 {17467 {