Try to fix a possible race condition with polymorphic record parameters

This commit is contained in:
gingerBill
2024-06-06 23:55:48 +01:00
parent 08612423b9
commit 7044a7d776
5 changed files with 46 additions and 48 deletions
+8 -23
View File
@@ -5912,15 +5912,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
if (operand->mode != Addressing_Type) {
error(operand->expr, "Expected a record type for '%.*s'", LIT(builtin_name));
} else {
Type *bt = base_type(operand->type);
if (bt->kind == Type_Struct) {
if (bt->Struct.polymorphic_params != nullptr) {
operand->value = exact_value_i64(bt->Struct.polymorphic_params->Tuple.variables.count);
}
} else if (bt->kind == Type_Union) {
if (bt->Union.polymorphic_params != nullptr) {
operand->value = exact_value_i64(bt->Union.polymorphic_params->Tuple.variables.count);
}
TypeTuple *tuple = get_record_polymorphic_params(operand->type);
if (tuple) {
operand->value = exact_value_i64(tuple->variables.count);
} else {
error(operand->expr, "Expected a record type for '%.*s'", LIT(builtin_name));
}
@@ -5952,20 +5946,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
Entity *param = nullptr;
i64 count = 0;
Type *bt = base_type(operand->type);
if (bt->kind == Type_Struct) {
if (bt->Struct.polymorphic_params != nullptr) {
count = bt->Struct.polymorphic_params->Tuple.variables.count;
if (index < count) {
param = bt->Struct.polymorphic_params->Tuple.variables[cast(isize)index];
}
}
} else if (bt->kind == Type_Union) {
if (bt->Union.polymorphic_params != nullptr) {
count = bt->Union.polymorphic_params->Tuple.variables.count;
if (index < count) {
param = bt->Union.polymorphic_params->Tuple.variables[cast(isize)index];
}
TypeTuple *tuple = get_record_polymorphic_params(operand->type);
if (tuple) {
count = tuple->variables.count;
if (index < count) {
param = tuple->variables[cast(isize)index];
}
} else {
error(operand->expr, "Expected a specialized polymorphic record type for '%.*s'", LIT(builtin_name));
+3 -8
View File
@@ -7331,14 +7331,9 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
gbString s = gb_string_make_reserve(heap_allocator(), e->token.string.len+3);
s = gb_string_append_fmt(s, "%.*s(", LIT(e->token.string));
Type *params = nullptr;
switch (bt->kind) {
case Type_Struct: params = bt->Struct.polymorphic_params; break;
case Type_Union: params = bt->Union.polymorphic_params; break;
}
if (params != nullptr) for_array(i, params->Tuple.variables) {
Entity *v = params->Tuple.variables[i];
TypeTuple *tuple = get_record_polymorphic_params(e->type);
if (tuple != nullptr) for_array(i, tuple->variables) {
Entity *v = tuple->variables[i];
String name = v->token.string;
if (i > 0) {
s = gb_string_append_fmt(s, ", ");
+13 -17
View File
@@ -564,19 +564,7 @@ gb_internal bool check_record_poly_operand_specialization(CheckerContext *ctx, T
gb_internal Entity *find_polymorphic_record_entity(GenTypesData *found_gen_types, isize param_count, Array<Operand> const &ordered_operands) {
for (Entity *e : found_gen_types->types) {
Type *t = base_type(e->type);
TypeTuple *tuple = nullptr;
switch (t->kind) {
case Type_Struct:
if (t->Struct.polymorphic_params) {
tuple = &t->Struct.polymorphic_params->Tuple;
}
break;
case Type_Union:
if (t->Union.polymorphic_params) {
tuple = &t->Union.polymorphic_params->Tuple;
}
break;
}
TypeTuple *tuple = get_record_polymorphic_params(t);
GB_ASSERT_MSG(tuple != nullptr, "%s :: %s", type_to_string(e->type), type_to_string(t));
GB_ASSERT(param_count == tuple->variables.count);
@@ -663,6 +651,8 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *
&struct_type->Struct.is_polymorphic,
node, poly_operands
);
wait_signal_set(&struct_type->Struct.polymorphic_wait_signal);
struct_type->Struct.is_poly_specialized = check_record_poly_operand_specialization(ctx, struct_type, poly_operands, &struct_type->Struct.is_polymorphic);
if (original_type_for_poly) {
GB_ASSERT(named_type != nullptr);
@@ -712,6 +702,8 @@ gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *no
&union_type->Union.is_polymorphic,
node, poly_operands
);
wait_signal_set(&union_type->Union.polymorphic_wait_signal);
union_type->Union.is_poly_specialized = check_record_poly_operand_specialization(ctx, union_type, poly_operands, &union_type->Union.is_polymorphic);
if (original_type_for_poly) {
GB_ASSERT(named_type != nullptr);
@@ -1453,12 +1445,14 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special
return true;
}
wait_for_record_polymorphic_params(s);
wait_for_record_polymorphic_params(t);
if (t->Struct.polymorphic_parent == s->Struct.polymorphic_parent &&
s->Struct.polymorphic_params != nullptr &&
t->Struct.polymorphic_params != nullptr) {
TypeTuple *s_tuple = &s->Struct.polymorphic_params->Tuple;
TypeTuple *t_tuple = &t->Struct.polymorphic_params->Tuple;
TypeTuple *s_tuple = get_record_polymorphic_params(s);
TypeTuple *t_tuple = get_record_polymorphic_params(t);
GB_ASSERT(t_tuple->variables.count == s_tuple->variables.count);
for_array(i, s_tuple->variables) {
Entity *s_e = s_tuple->variables[i];
@@ -1506,12 +1500,14 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special
return true;
}
wait_for_record_polymorphic_params(s);
wait_for_record_polymorphic_params(t);
if (t->Union.polymorphic_parent == s->Union.polymorphic_parent &&
s->Union.polymorphic_params != nullptr &&
t->Union.polymorphic_params != nullptr) {
TypeTuple *s_tuple = &s->Union.polymorphic_params->Tuple;
TypeTuple *t_tuple = &t->Union.polymorphic_params->Tuple;
TypeTuple *s_tuple = get_record_polymorphic_params(s);
TypeTuple *t_tuple = get_record_polymorphic_params(t);
GB_ASSERT(t_tuple->variables.count == s_tuple->variables.count);
for_array(i, s_tuple->variables) {
Entity *s_e = s_tuple->variables[i];
+4
View File
@@ -2031,6 +2031,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) {
} else {
add_type_info_type_internal(c, t_type_info_ptr);
}
wait_for_record_polymorphic_params(bt);
add_type_info_type_internal(c, bt->Union.polymorphic_params);
for_array(i, bt->Union.variants) {
add_type_info_type_internal(c, bt->Union.variants[i]);
@@ -2063,6 +2064,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) {
}
}
}
wait_for_record_polymorphic_params(bt);
add_type_info_type_internal(c, bt->Struct.polymorphic_params);
for_array(i, bt->Struct.fields) {
Entity *f = bt->Struct.fields[i];
@@ -2292,6 +2294,7 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) {
} else {
add_min_dep_type_info(c, t_type_info_ptr);
}
wait_for_record_polymorphic_params(bt);
add_min_dep_type_info(c, bt->Union.polymorphic_params);
for_array(i, bt->Union.variants) {
add_min_dep_type_info(c, bt->Union.variants[i]);
@@ -2321,6 +2324,7 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) {
}
}
}
wait_for_record_polymorphic_params(bt);
add_min_dep_type_info(c, bt->Struct.polymorphic_params);
for_array(i, bt->Struct.fields) {
Entity *f = bt->Struct.fields[i];
+18
View File
@@ -140,6 +140,7 @@ struct TypeStruct {
i64 custom_field_align;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
Wait_Signal polymorphic_wait_signal;
Type * soa_elem;
i32 soa_count;
@@ -167,6 +168,7 @@ struct TypeUnion {
i64 custom_align;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
Wait_Signal polymorphic_wait_signal;
i16 tag_size;
bool is_polymorphic;
@@ -1093,6 +1095,7 @@ gb_internal Type *alloc_type_struct() {
gb_internal Type *alloc_type_struct_complete() {
Type *t = alloc_type(Type_Struct);
wait_signal_set(&t->Struct.fields_wait_signal);
wait_signal_set(&t->Struct.polymorphic_wait_signal);
return t;
}
@@ -2136,15 +2139,30 @@ gb_internal bool is_type_polymorphic_record_unspecialized(Type *t) {
return false;
}
gb_internal void wait_for_record_polymorphic_params(Type *t) {
t = base_type(t);
switch (t->kind) {
case Type_Struct:
wait_signal_until_available(&t->Struct.polymorphic_wait_signal);
break;
case Type_Union:
wait_signal_until_available(&t->Union.polymorphic_wait_signal);
break;
}
}
gb_internal TypeTuple *get_record_polymorphic_params(Type *t) {
t = base_type(t);
switch (t->kind) {
case Type_Struct:
wait_signal_until_available(&t->Struct.polymorphic_wait_signal);
if (t->Struct.polymorphic_params) {
return &t->Struct.polymorphic_params->Tuple;
}
break;
case Type_Union:
wait_signal_until_available(&t->Union.polymorphic_wait_signal);
if (t->Union.polymorphic_params) {
return &t->Union.polymorphic_params->Tuple;
}