From 7ca22e1e3aa0974094e04fb4dda803b4657733e1 Mon Sep 17 00:00:00 2001 From: Vic Nightfall Date: Sun, 29 Sep 2024 19:07:24 +0200 Subject: [PATCH] Work on reflection data --- src/compiler.pr | 37 +++++++++++++++++++--------------- src/toolchain.pr | 2 +- std/reflection.pr | 51 +++++++++++++++++++++++++++-------------------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/compiler.pr b/src/compiler.pr index 5614608..d4499b4 100644 --- a/src/compiler.pr +++ b/src/compiler.pr @@ -9124,6 +9124,10 @@ def push_structural_members(tpe: &typechecking::Type, global: Value, module: &to } def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &toolchain::Module, cache: &Vector(TypeEntry)) -> &Value { + if not is_stub(tpe) { + all_types.add(tpe) + } + if toolchain::no_stdlib { return NO_VALUE } if tpe.kind == typechecking::TypeKind::BOX { @@ -9489,24 +9493,24 @@ def make_global_data(name: Str, value: size_t, state: &State) { state.module.imported.add(name) } +export let all_types = set::make(type &typechecking::Type) + export def generate_reflection_data() { let data = io::make_stream() let strings = [ strings = io::make_stream(), map = map::make(size_t) ] !&UniquedStrings - for var key in @types_to_resolve.keys() { - let to_resolve = types_to_resolve(key) - generate_reflection_data_1(to_resolve.tpe, data, strings) + for var tpe in @all_types.keys() { + generate_reflection_data_1(tpe, data, strings) } - for var key in @types_to_resolve.keys() { - let to_resolve = types_to_resolve(key) - generate_reflection_data_2(to_resolve.tpe, data, strings) + for var tpe in @all_types.keys() { + generate_reflection_data_2(tpe, data, strings) } make_global_data("__reflection_data", data, toolchain::types_state) make_global_data("__reflection_data_size", data.data().size, toolchain::types_state) make_global_data("__reflection_strings", strings.strings, toolchain::types_state) - make_global_data("__reflection_num_types", types_to_resolve.size, toolchain::types_state) + make_global_data("__reflection_num_types", all_types.size, toolchain::types_state) } type UniquedStrings = struct { @@ -9524,8 +9528,6 @@ def write_zt(uniqued: &UniquedStrings, s: Str) -> int { } def generate_reflection_data_2(tpe: &typechecking::Type, data: &ByteStream, strings: &UniquedStrings) { - if tpe.kind == typechecking::TypeKind::STUB { return } - // Collect type members let type_members = vector::make(typechecking::TypeEntryMember) for var member in typechecking::iterate_member_functions(tpe) { @@ -9541,7 +9543,7 @@ def generate_reflection_data_2(tpe: &typechecking::Type, data: &ByteStream, stri data.write(member.function.parameter_t.length !int) for var arg in member.function.parameter_t { - data.write(arg.tpe.hash) // TODO Do we want function argument names maybe? + data.write(arg.tpe.hash if arg.tpe else 0) // TODO Do we want function argument names maybe? } data.write(member.function.return_t.length !int) for var t in member.function.return_t { @@ -9566,7 +9568,7 @@ def generate_reflection_data_2(tpe: &typechecking::Type, data: &ByteStream, stri case typechecking::TypeKind::POINTER, typechecking::TypeKind::REFERENCE, typechecking::TypeKind::WEAK_REF, typechecking::TypeKind::ARRAY, typechecking::TypeKind::STATIC_ARRAY - data.write(tpe.tpe.hash) + data.write(tpe.tpe.hash if tpe.tpe else 0) case typechecking::TypeKind::TUPLE for var t in tpe.return_t { data.write(t.hash) @@ -9586,12 +9588,12 @@ def generate_reflection_data_2(tpe: &typechecking::Type, data: &ByteStream, stri } def generate_reflection_data_1(tpe: &typechecking::Type, data: &ByteStream, strings: &UniquedStrings) { - if tpe.kind == typechecking::TypeKind::STUB { return } - data.write(tpe.kind) // This does rely on the values beind the same data.write(strings.write_zt(tpe.name)) - data.write(strings.write_zt(tpe.module.module)) + data.write(strings.write_zt(tpe.module.module if tpe.module else to_str(""))) data.write(tpe.hash) + + print(tpe.kind, " ", tpe.name, " ", (tpe.module.module if tpe.module else to_str("")), " ", tpe.hash, "\n") switch tpe.kind { case typechecking::TypeKind::WORD @@ -9604,12 +9606,15 @@ def generate_reflection_data_1(tpe: &typechecking::Type, data: &ByteStream, stri case typechecking::TypeKind::STRUCT, typechecking::TypeKind::UNION data.write(tpe.size !int) data.write(tpe.align !int) - data.write(tpe.fields.size) + data.write(tpe.fields.size !int) + + print("\tsize: ", tpe.size, " align: ", tpe.align, " members: ", tpe.fields.size, "\n") for var i in 0..tpe.fields.size { let field = tpe.fields(i) let member = tpe.field_types(field.index) data.write(strings.write_zt(field.name)) data.write(member.offset !int) + print("\tname: ", field.name, " offset: ", member.offset, "\n") } case typechecking::TypeKind::STATIC_ARRAY data.write(tpe.size) @@ -9623,7 +9628,7 @@ def generate_reflection_data_1(tpe: &typechecking::Type, data: &ByteStream, stri data.write(tpe.align !int) data.write(not tpe.unsig) case typechecking::TypeKind::STRUCTURAL - data.write(tpe.members.length) + data.write(tpe.members.length !int) for var member in tpe.members { data.write(strings.write_zt(member.name)) data.write(member.parameter_t.length !int) diff --git a/src/toolchain.pr b/src/toolchain.pr index ea0776f..e6b6dec 100644 --- a/src/toolchain.pr +++ b/src/toolchain.pr @@ -840,8 +840,8 @@ export def compile_main_file(filename: String) { } debug::trace("Resolving types") - compiler::generate_reflection_data() compiler::resolve_types() // TODO Remove this function + compiler::generate_reflection_data() debug::trace("Creating builtin functions") compiler::create_builtin_functions() diff --git a/std/reflection.pr b/std/reflection.pr index 866c64b..109ca37 100644 --- a/std/reflection.pr +++ b/std/reflection.pr @@ -192,7 +192,7 @@ import io import map import std -var types: &Map(size_t, Type) +var types: &Map(uint64, Type) load_types(__reflection_data, @__reflection_data_size, @__reflection_num_types, __reflection_strings) @@ -206,7 +206,7 @@ def load_types(input: *uint8, size: size_t, num: size_t, strings: *char) { defer close(fp) if not types { - types = map::make(size_t, Type) + types = map::make(uint64, Type) } var index = 0 @@ -214,7 +214,9 @@ def load_types(input: *uint8, size: size_t, num: size_t, strings: *char) { let kind = fp.read(TypeKind) let name = make_slice(strings, fp.read(int)) let module = make_slice(strings, fp.read(int)) - let id = fp.read(size_t) + let id = fp.read(uint64) + + print(kind, " ", name, " ", module, " ", id, "\n") switch kind { case TypeKind::BOOL @@ -234,8 +236,13 @@ def load_types(input: *uint8, size: size_t, num: size_t, strings: *char) { let size = fp.read(int) let align = fp.read(int) let members = zero_allocate(Field, fp.read(int)) + + print("\tsize: ", size, " align: ", align, " members: ", members.size, "\n") + for var i in 0..members.size { - members(i) = [ name = make_slice(strings, fp.read(int)), offset = fp.read(int) ] !Field + let field = [ name = make_slice(strings, fp.read(int)), offset = fp.read(int) ] !Field + members(i) = field + print("\tname: ", field.name, " offset: ", field.offset, "\n") } if kind == TypeKind::STRUCT { @@ -320,11 +327,11 @@ def load_types(input: *uint8, size: size_t, num: size_t, strings: *char) { let arguments = allocate_ref(type weak Type, fp.read(int)) for var i in 0..arguments.size { - arguments(i) = type_id(fp.read(size_t)) + arguments(i) = type_id(fp.read(uint64)) } let returns = allocate_ref(type weak Type, fp.read(int)) for var i in 0..returns.size { - returns(i) = type_id(fp.read(size_t)) + returns(i) = type_id(fp.read(uint64)) } member.arguments = arguments @@ -336,65 +343,65 @@ def load_types(input: *uint8, size: size_t, num: size_t, strings: *char) { let rec = tpe !StructT for var i in 0..rec.members.size { let f = *rec.members(i) - f.tpe = type_id(fp.read(size_t)) + f.tpe = type_id(fp.read(uint64)) } } else if tpe.type == UnionT { let rec = tpe !UnionT for var i in 0..rec.members.size { let f = *rec.members(i) - f.tpe = type_id(fp.read(size_t)) + f.tpe = type_id(fp.read(uint64)) } } else if tpe.type == InterfaceT { let intf = tpe !InterfaceT for var i in 0..intf.members.size { let m = *intf.members(i) for var i in 0..m.arguments.size { - m.arguments(i) = type_id(fp.read(size_t)) + m.arguments(i) = type_id(fp.read(uint64)) } for var i in 0..m.returns.size { - m.returns(i) = type_id(fp.read(size_t)) + m.returns(i) = type_id(fp.read(uint64)) } } } else if tpe.type == PointerT { - (tpe !PointerT).tpe = type_id(fp.read(size_t)) + (tpe !PointerT).tpe = type_id(fp.read(uint64)) } else if tpe.type == ReferenceT { - (tpe !ReferenceT).tpe = type_id(fp.read(size_t)) + (tpe !ReferenceT).tpe = type_id(fp.read(uint64)) } else if tpe.type == WeakReferenceT { - (tpe !WeakReferenceT).tpe = type_id(fp.read(size_t)) + (tpe !WeakReferenceT).tpe = type_id(fp.read(uint64)) } else if tpe.type == ArrayT { - (tpe !ArrayT).tpe = type_id(fp.read(size_t)) + (tpe !ArrayT).tpe = type_id(fp.read(uint64)) } else if tpe.type == StaticArrayT { - (tpe !StaticArrayT).tpe = type_id(fp.read(size_t)) + (tpe !StaticArrayT).tpe = type_id(fp.read(uint64)) } else if (tpe.type == VariantT) { let vnt = tpe !VariantT for var i in 0..vnt.variants.size { - vnt.variants(i) = type_id(fp.read(size_t)) + vnt.variants(i) = type_id(fp.read(uint64)) } } else if (tpe.type == TupleT) { let tuple = tpe !TupleT for var i in 0..tuple.elements.size { - tuple.elements(i) = type_id(fp.read(size_t)) + tuple.elements(i) = type_id(fp.read(uint64)) } } else if (tpe.type == FunctionT) { let fun = tpe !FunctionT for var i in 0..fun.arguments.size { - fun.arguments(i) = type_id(fp.read(size_t)) + fun.arguments(i) = type_id(fp.read(uint64)) } for var i in 0..fun.returns.size { - fun.returns(i) = type_id(fp.read(size_t)) + fun.returns(i) = type_id(fp.read(uint64)) } } else if (tpe.type == ClosureT) { let fun = tpe !ClosureT for var i in 0..fun.arguments.size { - fun.arguments(i) = type_id(fp.read(size_t)) + fun.arguments(i) = type_id(fp.read(uint64)) } for var i in 0..fun.returns.size { - fun.returns(i) = type_id(fp.read(size_t)) + fun.returns(i) = type_id(fp.read(uint64)) } } } } -def type_id(index: size_t) -> Type { +def type_id(index: uint64) -> Type { return types(index) } \ No newline at end of file