@@ -9458,148 +9458,144 @@ def generate_vtable_function(function: &Function, fdef: typechecking::FunctionDe
94589458 ] !InsnSwitch
94599459 push_insn(swtch, state)
94609460
9461- let hashes = set::make(uint64)
9462- let keys = map::keys(typechecking::type_registry)
9463- for var i in 0..keys.size {
9464- let type_entry = typechecking::type_registry(keys(i))
9465- if is_ref(type_entry.tpe) and typechecking::implements(type_entry, first_param, state.scope) {
9466- // FIXME This whole branch isn't working yet because interfaces don't work right now
9467- let hash = type_entry.id
9468- if hashes.contains(hash) { continue }
9469- hashes.add(hash)
9461+ let intf = first_param.resolve()
9462+ assert intf.implementors
9463+ for var key in @intf.implementors.keys() {
9464+ let functions = intf.implementors(key)
9465+ let implementor = key.resolve()
9466+ let hash = key !uint64
94709467
9471- //let generic = typechecking::get_generic(type_entry.tpe)
9472- //if generic and generic.tc_incomplete { continue }
9473- if not type_entry.tpe { continue }
9468+ //let generic = typechecking::get_generic(type_entry.tpe)
9469+ //if generic and generic.tc_incomplete { continue }
94749470
9475- state.module.imported.add(type_entry.tpe .type_name)
9471+ state.module.imported.add(implementor .type_name)
94769472
9477- let parameter_t = vector::copy(ftpe.parameter_t)
9478- parameter_t(0) = [ tpe = type_entry .id ] !typechecking::NamedParameter
9479-
9480- var score = std::MAX_INT32 !int
9481- var fun: &typechecking::FunctionDef
9482- var module: &toolchain::Module = null
9483- /*for var member in typechecking::iterate_member_functions(type_entry) {
9484- if member.function.name != ftpe.name { continue }
9485- let s = typechecking::overload_score(member.function, parameter_t, state.module, true, local_type_defs = make_local_type_defs())
9486- if s >= 0 and s < score {
9487- fun = member.function
9488- module = member .module
9489- score = s
9490- }
9491- }*/
9473+ let parameter_t = vector::copy(ftpe.parameter_t)
9474+ parameter_t(0) = [ tpe = implementor .id ] !typechecking::NamedParameter
9475+
9476+ var score = std::MAX_INT32 !int
9477+ var fun: &typechecking::FunctionDef
9478+ var module: &toolchain::Module = null
9479+
9480+ for var f in functions {
9481+ let fdef = f.fdef
9482+ if typechecking::overload_score(fdef, parameter_t, state.scope, true) == 0 {
9483+ fun = fdef
9484+ module = f .module
9485+ break
9486+ }
9487+ }
94929488
9493- var kind = 0
9494- if not fun {
9495- if function.unmangled.starts_with("__set_") and function.unmangled.ends_with("__") {
9496- kind = 1
9497- } else if function.args.length == 1 {
9498- kind = 2
9499- } else {
9500- continue
9501- }
9489+ if not fun { assert }
9490+
9491+ var kind = 0
9492+ if not fun {
9493+ if function.unmangled.starts_with("__set_") and function.unmangled.ends_with("__") {
9494+ kind = 1
9495+ } else if function.args.length == 1 {
9496+ kind = 2
95029497 } else {
9503- predeclare_function(@fun, state.module)
9504- state.module.imported.add(fun.name)
9498+ continue
9499+ }
9500+ } else {
9501+ predeclare_function(@fun, state.module)
9502+ state.module.imported.add(fun.name)
95059503
9506- if consteval::is_static {
9507- let fun = scope::get_function(module.scope, parser::make_identifier(fun.unmangled), parameter_t, false, false, false)
9508- let val = consteval::compile_function(fun, state.scope)
9509- import_structures(val.get_type(), state.module)
9510- }
9504+ if consteval::is_static {
9505+ let fun = scope::get_function(module.scope, parser::make_identifier(fun.unmangled), parameter_t, false, false, false)
9506+ let val = consteval::compile_function(fun, state.scope)
9507+ import_structures(val.get_type(), state.module)
95119508 }
9509+ }
95129510
9513- if kind != 0 and type_entry.tpe .kind != typechecking::TypeKind::STRUCT { continue }
9511+ if kind != 0 and implementor .kind != typechecking::TypeKind::STRUCT { continue }
95149512
9515- if not consteval::is_static {
9516- import_structure(type_entry.tpe , state.module)
9517- }
9513+ if not consteval::is_static {
9514+ import_structure(implementor , state.module)
9515+ }
95189516
9519- let if_true = make_label(state)
9520- push_label(if_true, state)
9521-
9522- let svalue = [
9523- label_ = if_true,
9524- value = [ kind = ValueKind::INT, i = hash, tpe = builtins::int64_ ] !Value
9525- ] !SwitchValue
9526- switch_values.push(svalue)
9517+ let if_true = make_label(state)
9518+ push_label(if_true, state)
9519+
9520+ let svalue = [
9521+ label_ = if_true,
9522+ value = [ kind = ValueKind::INT, i = hash, tpe = builtins::int64_ ] !Value
9523+ ] !SwitchValue
9524+ switch_values.push(svalue)
95279525
9528-
9529- let target_type = fun.to_type().resolve().parameter_t(0).tpe if fun else type_entry.id
9530- let reference = convert_ref_to_ref(target_type, [ kind = ValueKind::LOCAL, tpe = first_param, name = "__ref.value"] !Value, null, state)
9531-
9532- if kind == 0 {
9533- let args = allocate_ref(Value, vector::length(ftpe.parameter_t))
9534- args(0) = reference
9535- for var i in 1..vector::length(ftpe.parameter_t) {
9536- let np = ftpe.parameter_t(i)
9537- args(i) = [ kind = ValueKind::LOCAL, tpe = np.tpe, name = np.name + ".value" ] !Value
9526+ let target_type = fun.to_type().resolve().parameter_t(0).tpe if fun else implementor.id
9527+ let reference = convert_ref_to_ref(target_type, [ kind = ValueKind::LOCAL, tpe = first_param, name = "__ref.value"] !Value, null, state)
9528+
9529+ if kind == 0 {
9530+ let args = allocate_ref(Value, vector::length(ftpe.parameter_t))
9531+ args(0) = reference
9532+ for var i in 1..vector::length(ftpe.parameter_t) {
9533+ let np = ftpe.parameter_t(i)
9534+ args(i) = [ kind = ValueKind::LOCAL, tpe = np.tpe, name = np.name + ".value" ] !Value
9535+ }
9536+ let r = state.call(fun.name, ret_tpe, args)
9537+ state.ret(r)
9538+ } else if kind == 1 {
9539+ // Setter
9540+ var deref = state.extract_value(pointer(implementor.id), reference, [1])
9541+ var value = state.load(implementor.id, deref)
9542+ let name = function.unmangled.slice(6, function.unmangled.length() - 2)
9543+ var findex: size_t = 0
9544+ var ftpe: &typechecking::Type
9545+ for var field in @implementor.fields {
9546+ if field.name == name {
9547+ findex = field.index
9548+ ftpe = field.tpe
95389549 }
9539- let r = state.call(fun.name, ret_tpe, args)
9540- state.ret(r)
9541- } else if kind == 1 {
9542- // Setter
9543- var deref = state.extract_value(pointer(type_entry.tpe), reference, [1])
9544- var value = state.load(type_entry.tpe, deref)
9545- let name = function.unmangled.slice(6, function.unmangled.length() - 2)
9546- var findex: size_t = 0
9547- var ftpe: &typechecking::Type
9548- for var field in @type_entry.tpe.resolve().fields {
9550+ }
9551+
9552+ let np = ftpe.parameter_t(1)
9553+ let arg = [ kind = ValueKind::LOCAL, tpe = np.tpe, name = np.name + ".value" ] !Value
9554+ value = state.insert_value(implementor.id, value, arg, [findex !int])
9555+ state.store(deref, value)
9556+ state.ret(NO_VALUE)
9557+ } else {
9558+ // Getter
9559+ let name = function.unmangled
9560+
9561+ var const_field: typechecking::StructMember
9562+ var is_const = false
9563+ let const_fields = implementor.const_fields
9564+ if const_fields {
9565+ for var field in @const_fields {
95499566 if field.name == name {
9550- findex = field.index
9551- ftpe = field.tpe
9567+ is_const = true
9568+ const_field = field
9569+ break
95529570 }
95539571 }
9572+ }
95549573
9555- let np = ftpe.parameter_t(1)
9556- let arg = [ kind = ValueKind::LOCAL, tpe = np.tpe, name = np.name + ".value" ] !Value
9557- value = state.insert_value(type_entry.tpe, value, arg, [findex !int])
9558- state.store(deref, value)
9559- state.ret(NO_VALUE)
9574+ if is_const {
9575+ let res = convert_to(null !&Value, @const_field.properties.value, ret_tpe, state)
9576+ state.ret(res)
95609577 } else {
9561- // Getter
9562- let name = function.unmangled
9578+ var stpe = implementor.id
9579+ // Resolve member
9580+ var deref = state.extract_value(pointer(stpe), reference, [1])
9581+ var value = state.load(stpe, deref)
9582+ value.addr = deref
95639583
9564- var const_field: typechecking::StructMember
9565- var is_const = false
9566- let const_fields = type_entry.tpe.resolve().const_fields
9567- if const_fields {
9568- for var field in @const_fields {
9569- if field.name == name {
9570- is_const = true
9571- const_field = field
9572- break
9573- }
9574- }
9584+ let vec = vector::make(Member)
9585+ if not resolve_member(vec, stpe, name) {
9586+ return
95759587 }
95769588
9577- if is_const {
9578- let res = convert_to(null !&Value, @const_field.properties.value, ret_tpe, state)
9579- state.ret(res)
9580- } else {
9581- var stpe = type_entry.tpe
9582- // Resolve member
9583- var deref = state.extract_value(pointer(stpe), reference, [1])
9584- var value = state.load(stpe, deref)
9585- value.addr = deref
9586-
9587- let vec = vector::make(Member)
9588- if not resolve_member(vec, stpe, name) {
9589- return
9590- }
9591-
9592- let len = vector::length(vec)
9593- for var i in 0..len {
9594- let j = len - i - 1
9595- let member = vec(j)
9596- value = walk_MemberAccess_struct(null, stpe, member, value, state)
9597- stpe = member.tpe
9598- }
9599- let val = load_value(value, null, state)
9600- increase_ref_count_of_value(val, null, state)
9601- state.ret(val)
9589+ let len = vector::length(vec)
9590+ for var i in 0..len {
9591+ let j = len - i - 1
9592+ let member = vec(j)
9593+ value = walk_MemberAccess_struct(null, stpe, member, value, state)
9594+ stpe = member.tpe
96029595 }
9596+ let val = load_value(value, null, state)
9597+ increase_ref_count_of_value(val, null, state)
9598+ state.ret(val)
96039599 }
96049600 }
96059601 }
0 commit comments