浏览代码

Correct deferred procedures

gingerBill 2 年之前
父节点
当前提交
1800030356
共有 1 个文件被更改,包括 109 次插入87 次删除
  1. 109 87
      src/llvm_backend_proc.cpp

+ 109 - 87
src/llvm_backend_proc.cpp

@@ -1160,7 +1160,13 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c
 
 	}
 
-	Entity **found = map_get(&p->module->procedure_values, value.value);
+	LLVMValueRef the_proc_value = value.value;
+
+	if (LLVMIsAConstantExpr(the_proc_value)) {
+		// NOTE(bill): it's a bit cast
+		the_proc_value = LLVMGetOperand(the_proc_value, 0);
+	}
+	Entity **found = map_get(&p->module->procedure_values, the_proc_value);
 	if (found != nullptr) {
 		Entity *e = *found;
 		if (e != nullptr && entity_has_deferred_procedure(e)) {
@@ -3156,14 +3162,89 @@ gb_internal void lb_add_values_to_array(lbProcedure *p, Array<lbValue> *args, lb
 		array_add(args, value);
 	}
 }
-gb_internal lbValue lb_build_call_expr_internal_with_arg_split_args(lbProcedure *p, lbValue value, TypeProc *pt, Ast *call, AstSplitArgs *split_args) {
-	ast_node(ce, CallExpr, call);
+
+gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
+	lbModule *m = p->module;
+
+	TypeAndValue tv = type_and_value_of_expr(expr);
+
+	ast_node(ce, CallExpr, expr);
+
+	TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
+	AddressingMode proc_mode = proc_tv.mode;
+	if (proc_mode == Addressing_Type) {
+		GB_ASSERT(ce->args.count == 1);
+		lbValue x = lb_build_expr(p, ce->args[0]);
+		lbValue y = lb_emit_conv(p, x, tv.type);
+		return y;
+	}
+
+	Ast *proc_expr = unparen_expr(ce->proc);
+	if (proc_mode == Addressing_Builtin) {
+		Entity *e = entity_of_node(proc_expr);
+		BuiltinProcId id = BuiltinProc_Invalid;
+		if (e != nullptr) {
+			id = cast(BuiltinProcId)e->Builtin.id;
+		} else {
+			id = BuiltinProc_DIRECTIVE;
+		}
+		return lb_build_builtin_proc(p, expr, tv, id);
+	}
+
+	// NOTE(bill): Regular call
+	lbValue value = {};
+
+	Entity *proc_entity = entity_of_node(proc_expr);
+	if (proc_entity != nullptr) {
+		if (proc_entity->flags & EntityFlag_Disabled) {
+			GB_ASSERT(tv.type == nullptr);
+			return {};
+		}
+	}
+
+	if (proc_expr->tav.mode == Addressing_Constant) {
+		ExactValue v = proc_expr->tav.value;
+		switch (v.kind) {
+		case ExactValue_Integer:
+			{
+				u64 u = big_int_to_u64(&v.value_integer);
+				lbValue x = {};
+				x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
+				x.type = t_uintptr;
+				x = lb_emit_conv(p, x, t_rawptr);
+				value = lb_emit_conv(p, x, proc_expr->tav.type);
+				break;
+			}
+		case ExactValue_Pointer:
+			{
+				u64 u = cast(u64)v.value_pointer;
+				lbValue x = {};
+				x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
+				x.type = t_uintptr;
+				x = lb_emit_conv(p, x, t_rawptr);
+				value = lb_emit_conv(p, x, proc_expr->tav.type);
+				break;
+			}
+		}
+	}
+
+	if (value.value == nullptr) {
+		value = lb_build_expr(p, proc_expr);
+	}
+
+	GB_ASSERT(value.value != nullptr);
+	Type *proc_type_ = base_type(value.type);
+	GB_ASSERT(proc_type_->kind == Type_Proc);
+	TypeProc *pt = &proc_type_->Proc;
+
+	GB_ASSERT(ce->split_args != nullptr);
 
 	auto args = array_make<lbValue>(permanent_allocator(), 0, pt->param_count);
 
 	bool vari_expand = (ce->ellipsis.pos.line != 0);
+	bool is_c_vararg = pt->c_vararg;
 
-	for_array(i, split_args->positional) {
+	for_array(i, ce->split_args->positional) {
 		Entity *e = pt->params->Tuple.variables[i];
 		if (e->kind == Entity_TypeName) {
 			array_add(&args, lb_const_nil(p->module, e->type));
@@ -3177,12 +3258,28 @@ gb_internal lbValue lb_build_call_expr_internal_with_arg_split_args(lbProcedure
 
 		if (pt->variadic && pt->variadic_index == i) {
 			lbValue variadic_args = lb_const_nil(p->module, e->type);
-			auto variadic = slice(split_args->positional, pt->variadic_index, split_args->positional.count);
+			auto variadic = slice(ce->split_args->positional, pt->variadic_index, ce->split_args->positional.count);
 			if (variadic.count != 0) {
 				// variadic call argument generation
 				Type *slice_type = e->type;
 				GB_ASSERT(slice_type->kind == Type_Slice);
-				if (vari_expand) {
+
+				if (is_c_vararg) {
+					GB_PANIC("TODO #c_vararg");
+					GB_ASSERT(!vari_expand);
+
+					Type *elem_type = slice_type->Slice.elem;
+
+					for (Ast *var_arg : variadic) {
+						lbValue arg = lb_build_expr(p, var_arg);
+						if (!is_type_any(elem_type)) {
+							array_add(&args, lb_emit_conv(p, arg, elem_type));
+						} else {
+							array_add(&args, lb_emit_conv(p, arg, default_type(arg.type)));
+						}
+					}
+					break;
+				} else if (vari_expand) {
 					GB_ASSERT(variadic.count == 1);
 					variadic_args = lb_build_expr(p, variadic[0]);
 					variadic_args = lb_emit_conv(p, variadic_args, slice_type);
@@ -3219,14 +3316,14 @@ gb_internal lbValue lb_build_call_expr_internal_with_arg_split_args(lbProcedure
 
 			break;
 		} else {
-			lbValue value = lb_build_expr(p, split_args->positional[i]);
+			lbValue value = lb_build_expr(p, ce->split_args->positional[i]);
 			lb_add_values_to_array(p, &args, value);
 		}
 	}
 
 	array_resize(&args, pt->param_count);
 
-	for (Ast *arg : split_args->named) {
+	for (Ast *arg : ce->split_args->named) {
 		ast_node(fv, FieldValue, arg);
 		GB_ASSERT(fv->field->kind == Ast_Ident);
 		String name = fv->field->Ident.token.string;
@@ -3243,6 +3340,7 @@ gb_internal lbValue lb_build_call_expr_internal_with_arg_split_args(lbProcedure
 
 
 	if (pt->params != nullptr)  {
+		GB_ASSERT(args.count >= pt->params->Tuple.variables.count);
 		for_array(arg_index, pt->params->Tuple.variables) {
 			Entity *e = pt->params->Tuple.variables[arg_index];
 
@@ -3269,84 +3367,8 @@ gb_internal lbValue lb_build_call_expr_internal_with_arg_split_args(lbProcedure
 	}
 
 
-	return lb_emit_call(p, value, args, ce->inlining);
-}
-
-gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
-	lbModule *m = p->module;
-
-	TypeAndValue tv = type_and_value_of_expr(expr);
-
-	ast_node(ce, CallExpr, expr);
-
-	TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
-	AddressingMode proc_mode = proc_tv.mode;
-	if (proc_mode == Addressing_Type) {
-		GB_ASSERT(ce->args.count == 1);
-		lbValue x = lb_build_expr(p, ce->args[0]);
-		lbValue y = lb_emit_conv(p, x, tv.type);
-		return y;
-	}
-
-	Ast *proc_expr = unparen_expr(ce->proc);
-	if (proc_mode == Addressing_Builtin) {
-		Entity *e = entity_of_node(proc_expr);
-		BuiltinProcId id = BuiltinProc_Invalid;
-		if (e != nullptr) {
-			id = cast(BuiltinProcId)e->Builtin.id;
-		} else {
-			id = BuiltinProc_DIRECTIVE;
-		}
-		return lb_build_builtin_proc(p, expr, tv, id);
-	}
-
-	// NOTE(bill): Regular call
-	lbValue value = {};
-
-	Entity *proc_entity = entity_of_node(proc_expr);
-	if (proc_entity != nullptr) {
-		if (proc_entity->flags & EntityFlag_Disabled) {
-			GB_ASSERT(tv.type == nullptr);
-			return {};
-		}
-	}
-
-	if (proc_expr->tav.mode == Addressing_Constant) {
-		ExactValue v = proc_expr->tav.value;
-		switch (v.kind) {
-		case ExactValue_Integer:
-			{
-				u64 u = big_int_to_u64(&v.value_integer);
-				lbValue x = {};
-				x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
-				x.type = t_uintptr;
-				x = lb_emit_conv(p, x, t_rawptr);
-				value = lb_emit_conv(p, x, proc_expr->tav.type);
-				break;
-			}
-		case ExactValue_Pointer:
-			{
-				u64 u = cast(u64)v.value_pointer;
-				lbValue x = {};
-				x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
-				x.type = t_uintptr;
-				x = lb_emit_conv(p, x, t_rawptr);
-				value = lb_emit_conv(p, x, proc_expr->tav.type);
-				break;
-			}
-		}
-	}
-
-	if (value.value == nullptr) {
-		value = lb_build_expr(p, proc_expr);
-	}
-
-	GB_ASSERT(value.value != nullptr);
-	Type *proc_type_ = base_type(value.type);
-	GB_ASSERT(proc_type_->kind == Type_Proc);
-	TypeProc *pt = &proc_type_->Proc;
-
-	GB_ASSERT(ce->split_args != nullptr);
-	return lb_build_call_expr_internal_with_arg_split_args(p, value, pt, expr, ce->split_args);
+	isize final_count = is_c_vararg ? args.count : pt->param_count;
+	auto call_args = array_slice(args, 0, final_count);
+	return lb_emit_call(p, value, call_args, ce->inlining);
 }