This commit is contained in:
nub31
2025-08-13 20:01:09 +02:00
parent bdcf0d3e7d
commit 46a2057e43
6 changed files with 41 additions and 35 deletions

View File

@@ -110,7 +110,7 @@ public partial class QBEGenerator
var value = EmitExpression(addressOf.Expression);
if (value.Kind != ValKind.Pointer)
{
throw new UnreachableException("Tried to take address of non-pointer type. This should have been causht in the type checker");
throw new UnreachableException("Tried to take address of non-pointer type. This should have been caught in the type checker");
}
return new Val(value.Name, addressOf.Type, ValKind.Direct);
@@ -333,11 +333,6 @@ public partial class QBEGenerator
_writer.Indented($"{destination} =l alloc8 {size}");
}
// if (structDef.InterfaceImplementations.Any())
// {
// _writer.Indented($"storel {destination}, {StructVtableName(structDef.Name)}");
// }
foreach (var field in structDef.Fields)
{
if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression))
@@ -345,7 +340,10 @@ public partial class QBEGenerator
valueExpression = field.Value.Value;
}
Debug.Assert(valueExpression != null);
if (valueExpression == null)
{
throw new UnreachableException("Value of field in uninitialized. This should have been caught in the type checker");
}
var offset = TmpName();
_writer.Indented($"{offset} =l add {destination}, {OffsetOf(structDef, field.Name)}");
@@ -423,13 +421,12 @@ public partial class QBEGenerator
private Val EmitStructFuncAccess(StructFuncAccessNode structFuncAccess)
{
var target = EmitExpression(structFuncAccess.Target);
Debug.Assert(target.Kind == ValKind.Pointer);
var target = EmitUnwrap(EmitExpression(structFuncAccess.Target));
var structDef = _definitionTable.LookupStruct(structFuncAccess.StructType.Name);
var func = StructFuncName(structDef.Name, structFuncAccess.Func);
return new Val(func, structFuncAccess.Type, ValKind.Direct, target.Name);
return new Val(func, structFuncAccess.Type, ValKind.Direct, target);
}
private Val EmitInterfaceFuncAccess(InterfaceFuncAccessNode interfaceFuncAccess)
@@ -449,13 +446,16 @@ public partial class QBEGenerator
var func = TmpName();
_writer.Indented($"{func} =l loadl {funcOffset}");
var dataPointer = TmpName();
_writer.Indented($"{dataPointer} =l add {target}, 8");
var data = TmpName();
_writer.Indented($"{data} =l add {target}, 8");
_writer.Indented($"{data} =l loadl {dataPointer}");
return new Val(func, interfaceFuncAccess.Type, ValKind.Direct, data);
}
private Val EmitInterfaceInitializer(InterfaceInitializerNode interfaceInitializer)
private Val EmitInterfaceInitializer(InterfaceInitializerNode interfaceInitializer, string? destination = null)
{
var implementation = EmitUnwrap(EmitExpression(interfaceInitializer.Implementation));
@@ -470,27 +470,28 @@ public partial class QBEGenerator
vtableOffset += interfaceImplementation.Functions.Count * 8;
}
var result = TmpName();
_writer.Indented($"{result} =l alloc8 16");
if (destination == null)
{
destination = TmpName();
_writer.Indented($"{destination} =l alloc8 {SizeOf(interfaceInitializer.InterfaceType)}");
}
var interfaceVtablePointer = TmpName();
_writer.Indented($"{interfaceVtablePointer} =l add {StructVtableName(interfaceInitializer.StructType.Name)}, {vtableOffset}");
_writer.Indented($"storel {interfaceVtablePointer}, {result}");
_writer.Indented($"storel {interfaceVtablePointer}, {destination}");
var objectPointer = TmpName();
_writer.Indented($"{objectPointer} =l add {result}, 8");
_writer.Indented($"{objectPointer} =l add {destination}, 8");
_writer.Indented($"storel {implementation}, {objectPointer}");
return new Val(result, interfaceInitializer.InterfaceType, ValKind.Direct);
return new Val(destination, interfaceInitializer.InterfaceType, ValKind.Direct);
}
private Val EmitFuncCall(FuncCallNode funcCall)
{
var expression = EmitExpression(funcCall.Expression);
var funcPointer = EmitUnwrap(expression);
var parameterStrings = new List<string>();
if (expression.ThisArg != null)
{
parameterStrings.Add($"l {expression.ThisArg}");
@@ -502,6 +503,7 @@ public partial class QBEGenerator
parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}");
}
var funcPointer = EmitUnwrap(expression);
if (funcCall.Type is VoidTypeNode)
{
_writer.Indented($"call {funcPointer}({string.Join(", ", parameterStrings)})");