Added Slice as it's own type info in userland
parent
670c9f9b74
commit
9b29c872ce
|
@ -5931,8 +5931,8 @@ size_t type_id_len() {
|
||||||
return array_length(all_type_ids);
|
return array_length(all_type_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t type_id_index(TypeTableEntryId id) {
|
size_t type_id_index(TypeTableEntry *entry) {
|
||||||
switch (id) {
|
switch (entry->id) {
|
||||||
case TypeTableEntryIdInvalid:
|
case TypeTableEntryIdInvalid:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case TypeTableEntryIdMetaType:
|
case TypeTableEntryIdMetaType:
|
||||||
|
@ -5952,6 +5952,8 @@ size_t type_id_index(TypeTableEntryId id) {
|
||||||
case TypeTableEntryIdArray:
|
case TypeTableEntryIdArray:
|
||||||
return 7;
|
return 7;
|
||||||
case TypeTableEntryIdStruct:
|
case TypeTableEntryIdStruct:
|
||||||
|
if (entry->data.structure.is_slice)
|
||||||
|
return 25;
|
||||||
return 8;
|
return 8;
|
||||||
case TypeTableEntryIdNumLitFloat:
|
case TypeTableEntryIdNumLitFloat:
|
||||||
return 9;
|
return 9;
|
||||||
|
|
|
@ -174,7 +174,7 @@ void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
|
||||||
const char *type_id_name(TypeTableEntryId id);
|
const char *type_id_name(TypeTableEntryId id);
|
||||||
TypeTableEntryId type_id_at_index(size_t index);
|
TypeTableEntryId type_id_at_index(size_t index);
|
||||||
size_t type_id_len();
|
size_t type_id_len();
|
||||||
size_t type_id_index(TypeTableEntryId id);
|
size_t type_id_index(TypeTableEntry *entry);
|
||||||
TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id);
|
TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id);
|
||||||
bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry);
|
bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry);
|
||||||
LinkLib *create_link_lib(Buf *name);
|
LinkLib *create_link_lib(Buf *name);
|
||||||
|
|
|
@ -6345,6 +6345,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
|
||||||
const TypeTableEntryId id = type_id_at_index(i);
|
const TypeTableEntryId id = type_id_at_index(i);
|
||||||
buf_appendf(contents, " %s,\n", type_id_name(id));
|
buf_appendf(contents, " %s,\n", type_id_name(id));
|
||||||
}
|
}
|
||||||
|
buf_appendf(contents, " Slice,\n");
|
||||||
buf_appendf(contents, "};\n\n");
|
buf_appendf(contents, "};\n\n");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -6357,6 +6358,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
|
||||||
" Int: Int,\n"
|
" Int: Int,\n"
|
||||||
" Float: Float,\n"
|
" Float: Float,\n"
|
||||||
" Pointer: Pointer,\n"
|
" Pointer: Pointer,\n"
|
||||||
|
" Slice: Slice,\n"
|
||||||
" Array: Array,\n"
|
" Array: Array,\n"
|
||||||
" Struct: Struct,\n"
|
" Struct: Struct,\n"
|
||||||
" FloatLiteral: void,\n"
|
" FloatLiteral: void,\n"
|
||||||
|
@ -6392,6 +6394,8 @@ static void define_builtin_compile_vars(CodeGen *g) {
|
||||||
" child: type,\n"
|
" child: type,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" pub const Slice = Pointer;\n"
|
||||||
|
"\n"
|
||||||
" pub const Array = struct {\n"
|
" pub const Array = struct {\n"
|
||||||
" len: usize,\n"
|
" len: usize,\n"
|
||||||
" child: type,\n"
|
" child: type,\n"
|
||||||
|
|
80
src/ir.cpp
80
src/ir.cpp
|
@ -15785,11 +15785,10 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na
|
||||||
|
|
||||||
Buf field_name = BUF_INIT;
|
Buf field_name = BUF_INIT;
|
||||||
buf_init_from_str(&field_name, type_name);
|
buf_init_from_str(&field_name, type_name);
|
||||||
auto entry = type_info_scope->decl_table.maybe_get(&field_name);
|
auto entry = type_info_scope->decl_table.get(&field_name);
|
||||||
buf_deinit(&field_name);
|
buf_deinit(&field_name);
|
||||||
assert(entry != nullptr);
|
|
||||||
|
|
||||||
TldVar *tld = (TldVar *)entry->value;
|
TldVar *tld = (TldVar *)entry;
|
||||||
assert(tld->base.id == TldIdVar);
|
assert(tld->base.id == TldIdVar);
|
||||||
|
|
||||||
VariableTableEntry *var = tld->var;
|
VariableTableEntry *var = tld->var;
|
||||||
|
@ -16071,6 +16070,38 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
enum_field_val->data.x_struct.fields = inner_fields;
|
enum_field_val->data.x_struct.fields = inner_fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto create_ptr_like_type_info = [ira](const char *name, TypeTableEntry *ptr_type_entry) {
|
||||||
|
ConstExprValue *result = create_const_vals(1);
|
||||||
|
result->special = ConstValSpecialStatic;
|
||||||
|
result->type = ir_type_info_get_type(ira, name);
|
||||||
|
|
||||||
|
ConstExprValue *fields = create_const_vals(4);
|
||||||
|
result->data.x_struct.fields = fields;
|
||||||
|
|
||||||
|
// is_const: bool
|
||||||
|
ensure_field_index(result->type, "is_const", 0);
|
||||||
|
fields[0].special = ConstValSpecialStatic;
|
||||||
|
fields[0].type = ira->codegen->builtin_types.entry_bool;
|
||||||
|
fields[0].data.x_bool = ptr_type_entry->data.pointer.is_const;
|
||||||
|
// is_volatile: bool
|
||||||
|
ensure_field_index(result->type, "is_volatile", 1);
|
||||||
|
fields[1].special = ConstValSpecialStatic;
|
||||||
|
fields[1].type = ira->codegen->builtin_types.entry_bool;
|
||||||
|
fields[1].data.x_bool = ptr_type_entry->data.pointer.is_volatile;
|
||||||
|
// alignment: u32
|
||||||
|
ensure_field_index(result->type, "alignment", 2);
|
||||||
|
fields[2].special = ConstValSpecialStatic;
|
||||||
|
fields[2].type = ira->codegen->builtin_types.entry_u32;
|
||||||
|
bigint_init_unsigned(&fields[2].data.x_bigint, ptr_type_entry->data.pointer.alignment);
|
||||||
|
// child: type
|
||||||
|
ensure_field_index(result->type, "child", 3);
|
||||||
|
fields[3].special = ConstValSpecialStatic;
|
||||||
|
fields[3].type = ira->codegen->builtin_types.entry_type;
|
||||||
|
fields[3].data.x_type = ptr_type_entry->data.pointer.child_type;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
ConstExprValue *result = nullptr;
|
ConstExprValue *result = nullptr;
|
||||||
switch (type_entry->id)
|
switch (type_entry->id)
|
||||||
{
|
{
|
||||||
|
@ -16139,34 +16170,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
}
|
}
|
||||||
case TypeTableEntryIdPointer:
|
case TypeTableEntryIdPointer:
|
||||||
{
|
{
|
||||||
result = create_const_vals(1);
|
result = create_ptr_like_type_info("Pointer", type_entry);
|
||||||
result->special = ConstValSpecialStatic;
|
|
||||||
result->type = ir_type_info_get_type(ira, "Pointer");
|
|
||||||
|
|
||||||
ConstExprValue *fields = create_const_vals(4);
|
|
||||||
result->data.x_struct.fields = fields;
|
|
||||||
|
|
||||||
// is_const: bool
|
|
||||||
ensure_field_index(result->type, "is_const", 0);
|
|
||||||
fields[0].special = ConstValSpecialStatic;
|
|
||||||
fields[0].type = ira->codegen->builtin_types.entry_bool;
|
|
||||||
fields[0].data.x_bool = type_entry->data.pointer.is_const;
|
|
||||||
// is_volatile: bool
|
|
||||||
ensure_field_index(result->type, "is_volatile", 1);
|
|
||||||
fields[1].special = ConstValSpecialStatic;
|
|
||||||
fields[1].type = ira->codegen->builtin_types.entry_bool;
|
|
||||||
fields[1].data.x_bool = type_entry->data.pointer.is_volatile;
|
|
||||||
// alignment: u32
|
|
||||||
ensure_field_index(result->type, "alignment", 2);
|
|
||||||
fields[2].special = ConstValSpecialStatic;
|
|
||||||
fields[2].type = ira->codegen->builtin_types.entry_u32;
|
|
||||||
bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment);
|
|
||||||
// child: type
|
|
||||||
ensure_field_index(result->type, "child", 3);
|
|
||||||
fields[3].special = ConstValSpecialStatic;
|
|
||||||
fields[3].type = ira->codegen->builtin_types.entry_type;
|
|
||||||
fields[3].data.x_type = type_entry->data.pointer.child_type;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TypeTableEntryIdArray:
|
case TypeTableEntryIdArray:
|
||||||
|
@ -16436,6 +16440,16 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
}
|
}
|
||||||
case TypeTableEntryIdStruct:
|
case TypeTableEntryIdStruct:
|
||||||
{
|
{
|
||||||
|
if (type_entry->data.structure.is_slice) {
|
||||||
|
Buf ptr_field_name = BUF_INIT;
|
||||||
|
buf_init_from_str(&ptr_field_name, "ptr");
|
||||||
|
TypeTableEntry *ptr_type = type_entry->data.structure.fields_by_name.get(&ptr_field_name)->type_entry;
|
||||||
|
ensure_complete_type(ira->codegen, ptr_type);
|
||||||
|
|
||||||
|
result = create_ptr_like_type_info("Slice", ptr_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = create_const_vals(1);
|
result = create_const_vals(1);
|
||||||
result->special = ConstValSpecialStatic;
|
result->special = ConstValSpecialStatic;
|
||||||
result->type = ir_type_info_get_type(ira, "Struct");
|
result->type = ir_type_info_get_type(ira, "Struct");
|
||||||
|
@ -16622,7 +16636,7 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
|
||||||
|
|
||||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||||
out_val->type = result_type;
|
out_val->type = result_type;
|
||||||
bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id));
|
bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry));
|
||||||
|
|
||||||
ConstExprValue *payload = ir_make_type_info_value(ira, type_entry);
|
ConstExprValue *payload = ir_make_type_info_value(ira, type_entry);
|
||||||
out_val->data.x_union.payload = payload;
|
out_val->data.x_union.payload = payload;
|
||||||
|
@ -16650,7 +16664,7 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
|
||||||
TypeTableEntry *result_type = var_value->data.x_type;
|
TypeTableEntry *result_type = var_value->data.x_type;
|
||||||
|
|
||||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||||
bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry->id));
|
bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry));
|
||||||
return result_type;
|
return result_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ test "type info: integer, floating point type info" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "type info: pointer, array and nullable type info" {
|
test "type info: pointer type info" {
|
||||||
comptime {
|
comptime {
|
||||||
const u32_ptr_info = @typeInfo(&u32);
|
const u32_ptr_info = @typeInfo(&u32);
|
||||||
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
|
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
|
||||||
|
@ -33,12 +33,31 @@ test "type info: pointer, array and nullable type info" {
|
||||||
assert(u32_ptr_info.Pointer.is_volatile == false);
|
assert(u32_ptr_info.Pointer.is_volatile == false);
|
||||||
assert(u32_ptr_info.Pointer.alignment == 4);
|
assert(u32_ptr_info.Pointer.alignment == 4);
|
||||||
assert(u32_ptr_info.Pointer.child == u32);
|
assert(u32_ptr_info.Pointer.child == u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "type info: slice type info" {
|
||||||
|
comptime {
|
||||||
|
const u32_slice_info = @typeInfo([]u32);
|
||||||
|
assert(TypeId(u32_slice_info) == TypeId.Slice);
|
||||||
|
assert(u32_slice_info.Slice.is_const == false);
|
||||||
|
assert(u32_slice_info.Slice.is_volatile == false);
|
||||||
|
assert(u32_slice_info.Slice.alignment == 4);
|
||||||
|
assert(u32_slice_info.Slice.child == u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "type info: array type info" {
|
||||||
|
comptime {
|
||||||
const arr_info = @typeInfo([42]bool);
|
const arr_info = @typeInfo([42]bool);
|
||||||
assert(TypeId(arr_info) == TypeId.Array);
|
assert(TypeId(arr_info) == TypeId.Array);
|
||||||
assert(arr_info.Array.len == 42);
|
assert(arr_info.Array.len == 42);
|
||||||
assert(arr_info.Array.child == bool);
|
assert(arr_info.Array.child == bool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "type info: nullable type info" {
|
||||||
|
comptime {
|
||||||
const null_info = @typeInfo(?void);
|
const null_info = @typeInfo(?void);
|
||||||
assert(TypeId(null_info) == TypeId.Nullable);
|
assert(TypeId(null_info) == TypeId.Nullable);
|
||||||
assert(null_info.Nullable.child == void);
|
assert(null_info.Nullable.child == void);
|
||||||
|
@ -100,11 +119,11 @@ test "type info: union info" {
|
||||||
assert(TypeId(typeinfo_info) == TypeId.Union);
|
assert(TypeId(typeinfo_info) == TypeId.Union);
|
||||||
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||||
assert(typeinfo_info.Union.tag_type == TypeId);
|
assert(typeinfo_info.Union.tag_type == TypeId);
|
||||||
assert(typeinfo_info.Union.fields.len == 25);
|
assert(typeinfo_info.Union.fields.len == 26);
|
||||||
assert(typeinfo_info.Union.fields[4].enum_field != null);
|
assert(typeinfo_info.Union.fields[4].enum_field != null);
|
||||||
assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
|
assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
|
||||||
assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
||||||
assert(typeinfo_info.Union.defs.len == 20);
|
assert(typeinfo_info.Union.defs.len == 21);
|
||||||
|
|
||||||
const TestNoTagUnion = union {
|
const TestNoTagUnion = union {
|
||||||
Foo: void,
|
Foo: void,
|
||||||
|
|
Loading…
Reference in New Issue