Browse Source

Update instrumentation signature to support `runtime.Source_Code_Location` as last parameter.

gingerBill 1 year ago
parent
commit
67dcd916e8
3 changed files with 20 additions and 7 deletions
  1. 10 5
      src/check_decl.cpp
  2. 2 0
      src/llvm_backend.hpp
  3. 8 2
      src/llvm_backend_opt.cpp

+ 10 - 5
src/check_decl.cpp

@@ -933,20 +933,23 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 		if (type == nullptr || type->kind != Type_Proc) {
 			return false;
 		}
-		if (type->Proc.calling_convention != ProcCC_CDecl) {
+		if (type->Proc.calling_convention != ProcCC_Contextless) {
 			return false;
 		}
 		if (type->Proc.result_count != 0) {
 			return false;
 		}
-		if (type->Proc.param_count != 2) {
+		if (type->Proc.param_count != 3) {
 			return false;
 		}
 		Type *p0 = type->Proc.params->Tuple.variables[0]->type;
 		Type *p1 = type->Proc.params->Tuple.variables[1]->type;
-		return is_type_rawptr(p0) && is_type_rawptr(p1);
+		Type *p3 = type->Proc.params->Tuple.variables[2]->type;
+		return is_type_rawptr(p0) && is_type_rawptr(p1) && are_types_identical(p3, t_source_code_location);
 	};
 
+	static char const *instrumentation_proc_type_str = "proc \"contextless\" (proc_address: rawptr, call_site_return_address: rawptr, loc: runtime.Source_Code_Location)";
+
 	if (ac.instrumentation_enter && ac.instrumentation_exit) {
 		error(e->token, "A procedure cannot be marked with both @(instrumentation_enter) and @(instrumentation_exit)");
 
@@ -954,8 +957,9 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 		e->flags |= EntityFlag_Require;
 	} else if (ac.instrumentation_enter) {
 		if (!is_valid_instrumentation_call(e->type)) {
+			init_core_source_code_location(ctx->checker);
 			gbString s = type_to_string(e->type);
-			error(e->token, "@(instrumentation_enter) procedures must have the type 'proc \"c\" (rawptr, rawptr)', got %s", s);
+			error(e->token, "@(instrumentation_enter) procedures must have the type '%s', got %s", instrumentation_proc_type_str, s);
 			gb_string_free(s);
 		}
 		MUTEX_GUARD(&ctx->info->instrumentation_mutex);
@@ -968,9 +972,10 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 		has_instrumentation = false;
 		e->flags |= EntityFlag_Require;
 	} else if (ac.instrumentation_exit) {
+		init_core_source_code_location(ctx->checker);
 		if (!is_valid_instrumentation_call(e->type)) {
 			gbString s = type_to_string(e->type);
-			error(e->token, "@(instrumentation_exit) procedures must have the type 'proc \"c\" (rawptr, rawptr)', got %s", s);
+			error(e->token, "@(instrumentation_exit) procedures must have the type '%s', got %s", instrumentation_proc_type_str, s);
 			gb_string_free(s);
 		}
 		MUTEX_GUARD(&ctx->info->instrumentation_mutex);

+ 2 - 0
src/llvm_backend.hpp

@@ -565,6 +565,8 @@ gb_internal String lb_filepath_ll_for_module(lbModule *m);
 
 gb_internal LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type);
 
+gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const &procedure, TokenPos const &pos);
+
 gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t ElementCount) {
 #if LB_USE_NEW_PASS_SYSTEM
 	return LLVMArrayType2(ElementType, ElementCount);

+ 8 - 2
src/llvm_backend_opt.cpp

@@ -385,7 +385,7 @@ gb_internal LLVMValueRef lb_run_instrumentation_pass_insert_call(lbProcedure *p,
 
 	lbValue cc = lb_find_procedure_value_from_entity(m, entity);
 
-	LLVMValueRef args[2] = {};
+	LLVMValueRef args[3] = {};
 	args[0] = p->value;
 
 	LLVMValueRef returnaddress_args[1] = {};
@@ -399,8 +399,14 @@ gb_internal LLVMValueRef lb_run_instrumentation_pass_insert_call(lbProcedure *p,
 	LLVMTypeRef call_type = LLVMIntrinsicGetType(m->ctx, id, nullptr, 0);
 	args[1] = LLVMBuildCall2(dummy_builder, call_type, ip, returnaddress_args, gb_count_of(returnaddress_args), "");
 
+	Token name = {};
+	if (p->entity) {
+		name = p->entity->token;
+	}
+	args[2] = lb_emit_source_code_location_as_global_ptr(p, name.string, name.pos).value;
+
 	LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(p->module, entity->type);
-	return LLVMBuildCall2(dummy_builder, fnp, cc.value, args, 2, "");
+	return LLVMBuildCall2(dummy_builder, fnp, cc.value, args, gb_count_of(args), "");
 }