Skip to content

Commit 65b17fc

Browse files
committed
Optimize calls to base getters in properties
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent e592a2b commit 65b17fc

File tree

4 files changed

+63
-91
lines changed

4 files changed

+63
-91
lines changed

src/AST/ClassExtensions.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,28 @@ public static Method GetBaseMethod(this Class @class, Method @override)
5555
return methods.FirstOrDefault(@override.CanOverride);
5656
}
5757

58-
public static Property GetBaseProperty(this Class @class, Property @override,
58+
public static Property GetBaseProperty(this Class @class, Property @override)
59+
{
60+
foreach (var @base in @class.Bases.Where(b => b.IsClass))
61+
{
62+
Class baseClass = @base.Class.OriginalClass ?? @base.Class;
63+
Property baseProperty = baseClass.Properties.Find(p =>
64+
(@override.GetMethod?.IsOverride == true &&
65+
@override.GetMethod.BaseMethod == p.GetMethod) ||
66+
(@override.SetMethod?.IsOverride == true &&
67+
@override.SetMethod.BaseMethod == p.SetMethod) ||
68+
(@override.Field != null && @override.Field == p.Field));
69+
if (baseProperty != null)
70+
return baseProperty;
71+
72+
baseProperty = GetBaseProperty(@base.Class, @override);
73+
if (baseProperty != null)
74+
return baseProperty;
75+
}
76+
return null;
77+
}
78+
79+
public static Property GetBasePropertyByName(this Class @class, Property @override,
5980
bool onlyFirstBase = false)
6081
{
6182
foreach (var @base in @class.Bases)
@@ -76,20 +97,13 @@ public static Property GetBaseProperty(this Class @class, Property @override,
7697
if (baseProperty != null)
7798
return baseProperty;
7899

79-
baseProperty = @base.Class.GetBaseProperty(@override, onlyFirstBase);
100+
baseProperty = @base.Class.GetBasePropertyByName(@override, onlyFirstBase);
80101
if (baseProperty != null)
81102
return baseProperty;
82103
}
83104
return null;
84105
}
85106

86-
public static bool HasNonAbstractBasePropertyInPrimaryBase(this Class @class, Property property)
87-
{
88-
var baseProperty = @class.GetBaseProperty(property, true);
89-
return baseProperty != null && !baseProperty.IsPure &&
90-
!((Class) baseProperty.OriginalNamespace).IsInterface;
91-
}
92-
93107
public static Property GetPropertyByName(this Class @class, string propertyName)
94108
{
95109
Property property = @class.Properties.Find(m => m.Name == propertyName);

src/Generator/Generators/CSharp/CSharpSources.cs

Lines changed: 38 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ private void GatherClassInternalFunctions(Class @class, bool includeCtors,
629629

630630
foreach (var method in @class.Methods)
631631
{
632-
if (!method.IsGenerated || ASTUtils.CheckIgnoreMethod(method))
632+
if (ASTUtils.CheckIgnoreMethod(method))
633633
continue;
634634

635635
if (method.IsConstructor)
@@ -640,10 +640,11 @@ private void GatherClassInternalFunctions(Class @class, bool includeCtors,
640640

641641
foreach (var prop in @class.Properties)
642642
{
643-
if (prop.GetMethod != null)
643+
if (prop.GetMethod?.Namespace == @class)
644644
tryAddOverload(prop.GetMethod);
645645

646-
if (prop.SetMethod != null && prop.SetMethod != prop.GetMethod)
646+
if (prop.SetMethod?.Namespace == @class &&
647+
prop.SetMethod != prop.GetMethod)
647648
tryAddOverload(prop.SetMethod);
648649
}
649650
}
@@ -894,25 +895,12 @@ private void GenerateFunctionSetter(Class @class, Property property)
894895
return;
895896
}
896897
property = actualProperty;
897-
var param = new Parameter
898-
{
899-
Name = "value",
900-
QualifiedType = property.SetMethod.Parameters[0].QualifiedType,
901-
Kind = ParameterKind.PropertyValue
902-
};
903898

904-
var parameters = new List<Parameter> { param };
905-
var @void = new QualifiedType(new BuiltinType(PrimitiveType.Void));
906-
if (property.SetMethod.SynthKind == FunctionSynthKind.AbstractImplCall)
907-
GenerateVirtualPropertyCall(property.SetMethod, @class.BaseClass,
908-
property, parameters, @void);
909-
else if (property.SetMethod.IsVirtual)
910-
GenerateVirtualPropertyCall(property.SetMethod, @class,
911-
property, parameters, @void);
912-
else if (property.SetMethod.OperatorKind == CXXOperatorKind.Subscript)
899+
if (property.SetMethod.OperatorKind == CXXOperatorKind.Subscript)
913900
GenerateIndexerSetter(property.SetMethod);
914901
else
915-
GenerateInternalFunctionCall(property.SetMethod, parameters, @void);
902+
GenerateFunctionInProperty(@class, property.SetMethod, actualProperty,
903+
new QualifiedType(new BuiltinType(PrimitiveType.Void)));
916904
}
917905

918906
private void GenerateFieldSetter(Field field, Class @class, QualifiedType fieldType)
@@ -1046,7 +1034,7 @@ private void GenerateIndexerSetter(Function function)
10461034

10471035
var internalFunction = GetFunctionNativeIdentifier(function);
10481036
var paramMarshal = GenerateFunctionParamMarshal(
1049-
function.Parameters[0], 0, function);
1037+
function.Parameters[0], 0);
10501038
string call = $@"{@internal}.{internalFunction}({
10511039
GetInstanceParam(function)}, {paramMarshal.Context.ArgumentPrefix}{paramMarshal.Name})";
10521040
if (type.IsPrimitiveType())
@@ -1205,14 +1193,8 @@ private void GenerateFunctionGetter(Class @class, Property property)
12051193
@class.Visit(TypePrinter)}."");");
12061194
return;
12071195
}
1208-
if (actualProperty.GetMethod.SynthKind == FunctionSynthKind.AbstractImplCall)
1209-
GenerateVirtualPropertyCall(actualProperty.GetMethod,
1210-
@class.BaseClass, actualProperty);
1211-
else if (actualProperty.GetMethod.IsVirtual)
1212-
GenerateVirtualPropertyCall(actualProperty.GetMethod,
1213-
@class, actualProperty);
1214-
else GenerateInternalFunctionCall(actualProperty.GetMethod,
1215-
actualProperty.GetMethod.Parameters, property.QualifiedType);
1196+
GenerateFunctionInProperty(@class, actualProperty.GetMethod, actualProperty,
1197+
property.QualifiedType);
12161198
}
12171199

12181200
private static Property GetActualProperty(Property property, Class c)
@@ -1223,6 +1205,21 @@ private static Property GetActualProperty(Property property, Class c)
12231205
p.GetMethod.InstantiatedFrom == property.GetMethod);
12241206
}
12251207

1208+
private void GenerateFunctionInProperty(Class @class, Method constituent,
1209+
Property property, QualifiedType type)
1210+
{
1211+
if (constituent.IsVirtual && (!property.IsOverride ||
1212+
@class.GetBaseProperty(property).IsPure || constituent.OriginalFunction != null))
1213+
GenerateFunctionCall(GetVirtualCallDelegate(constituent),
1214+
constituent, type);
1215+
else if (property.IsOverride &&
1216+
constituent.OriginalFunction == null)
1217+
WriteLine(property.GetMethod == constituent ?
1218+
"return base.{0};" : "base.{0} = value;", property.Name);
1219+
else
1220+
GenerateInternalFunctionCall(constituent, type);
1221+
}
1222+
12261223
private void GenerateFieldGetter(Field field, Class @class, QualifiedType returnType)
12271224
{
12281225
var name = ((Class) field.Namespace).Layout.Fields.First(
@@ -1403,7 +1400,7 @@ private void GenerateProperties(Class @class)
14031400
// check if overriding a property from a secondary base
14041401
Property rootBaseProperty;
14051402
var isOverride = prop.IsOverride &&
1406-
(rootBaseProperty = @class.GetBaseProperty(prop, true)) != null &&
1403+
(rootBaseProperty = @class.GetBasePropertyByName(prop, true)) != null &&
14071404
(rootBaseProperty.IsVirtual || rootBaseProperty.IsPure);
14081405

14091406
if (isOverride)
@@ -2601,29 +2598,14 @@ private void GenerateGetHashCode(Class @class)
26012598
Helpers.InstanceIdentifier}).GetHashCode();");
26022599
}
26032600

2604-
private void GenerateVirtualPropertyCall(Method method, Class @class,
2605-
Property property, List<Parameter> parameters = null,
2606-
QualifiedType returnType = default(QualifiedType))
2607-
{
2608-
if (property.IsOverride && !property.IsPure &&
2609-
method.SynthKind != FunctionSynthKind.AbstractImplCall &&
2610-
@class.HasNonAbstractBasePropertyInPrimaryBase(property))
2611-
WriteLine(parameters == null ?
2612-
"return base.{0};" : "base.{0} = value;", property.Name);
2613-
else
2614-
GenerateFunctionCall(GetVirtualCallDelegate(method),
2615-
parameters ?? method.Parameters, method, returnType);
2616-
}
2617-
26182601
private void GenerateVirtualFunctionCall(Method method,
26192602
bool forceVirtualCall = false)
26202603
{
26212604
if (!forceVirtualCall && method.IsGeneratedOverride() &&
26222605
!method.BaseMethod.IsPure)
26232606
GenerateManagedCall(method, true);
26242607
else
2625-
GenerateFunctionCall(GetVirtualCallDelegate(method),
2626-
method.Parameters, method);
2608+
GenerateFunctionCall(GetVirtualCallDelegate(method), method);
26272609
}
26282610

26292611
private string GetVirtualCallDelegate(Method method)
@@ -2749,12 +2731,8 @@ private void GenerateClassConstructor(Method method, Class @class)
27492731
}
27502732

27512733
public void GenerateInternalFunctionCall(Function function,
2752-
List<Parameter> parameters = null,
27532734
QualifiedType returnType = default(QualifiedType))
27542735
{
2755-
if (parameters == null)
2756-
parameters = function.Parameters;
2757-
27582736
var @class = function.Namespace as Class;
27592737

27602738
string @internal = Helpers.InternalStruct;
@@ -2763,11 +2741,11 @@ public void GenerateInternalFunctionCall(Function function,
27632741

27642742
var nativeFunction = GetFunctionNativeIdentifier(function);
27652743
var functionName = $"{@internal}.{nativeFunction}";
2766-
GenerateFunctionCall(functionName, parameters, function, returnType);
2744+
GenerateFunctionCall(functionName, function, returnType);
27672745
}
27682746

2769-
public void GenerateFunctionCall(string functionName, List<Parameter> parameters,
2770-
Function function, QualifiedType returnType = default(QualifiedType))
2747+
public void GenerateFunctionCall(string functionName, Function function,
2748+
QualifiedType returnType = default(QualifiedType))
27712749
{
27722750
if (function.IsPure)
27732751
{
@@ -2804,7 +2782,7 @@ public void GenerateFunctionCall(string functionName, List<Parameter> parameters
28042782
needsInstance = !method.IsStatic || operatorParam != null;
28052783
}
28062784

2807-
var @params = GenerateFunctionParamsMarshal(parameters, function);
2785+
var @params = GenerateFunctionParamsMarshal(function.Parameters);
28082786

28092787
var originalFunction = function.OriginalFunction ?? function;
28102788

@@ -3002,8 +2980,7 @@ public struct ParamMarshal
30022980
public bool HasUsingBlock;
30032981
}
30042982

3005-
public List<ParamMarshal> GenerateFunctionParamsMarshal(IEnumerable<Parameter> @params,
3006-
Function function = null)
2983+
public List<ParamMarshal> GenerateFunctionParamsMarshal(IEnumerable<Parameter> @params)
30072984
{
30082985
var marshals = new List<ParamMarshal>();
30092986

@@ -3013,18 +2990,20 @@ public List<ParamMarshal> GenerateFunctionParamsMarshal(IEnumerable<Parameter> @
30132990
if (param.Kind == ParameterKind.IndirectReturnType)
30142991
continue;
30152992

3016-
marshals.Add(GenerateFunctionParamMarshal(param, paramIndex++, function));
2993+
marshals.Add(GenerateFunctionParamMarshal(param, paramIndex++));
30172994
}
30182995

30192996
return marshals;
30202997
}
30212998

3022-
private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
3023-
Function function = null)
2999+
private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex)
30243000
{
30253001
// Do not delete instance in MS ABI.
30263002
var name = param.Name;
3027-
param.Name = param.Kind == ParameterKind.ImplicitDestructorParameter ? "0" : name;
3003+
var function = (Function) param.Namespace;
3004+
param.Name = param.Kind == ParameterKind.ImplicitDestructorParameter ? "0" :
3005+
function.IsGenerated || function.OperatorKind == CXXOperatorKind.Subscript ?
3006+
name : "value";
30283007

30293008
var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);
30303009
var paramMarshal = new ParamMarshal { Name = argName, Param = param };

src/Generator/Passes/GetterSetterToPropertyPass.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ private static void ProcessOverridden(Class @class, Property property)
239239
if (!property.IsOverride)
240240
return;
241241

242-
Property baseProperty = GetBaseProperty(@class, property);
242+
Property baseProperty = @class.GetBaseProperty(property);
243243
if (baseProperty == null)
244244
{
245245
if (property.HasSetter)
@@ -263,27 +263,6 @@ private static void ProcessOverridden(Class @class, Property property)
263263
}
264264
}
265265

266-
private static Property GetBaseProperty(Class @class, Property @override)
267-
{
268-
foreach (var @base in @class.Bases)
269-
{
270-
Class baseClass = @base.Class.OriginalClass ?? @base.Class;
271-
Property baseProperty = baseClass.Properties.Find(p =>
272-
(@override.GetMethod?.IsOverride == true &&
273-
@override.GetMethod.BaseMethod == p.GetMethod) ||
274-
(@override.SetMethod?.IsOverride == true &&
275-
@override.SetMethod.BaseMethod == p.SetMethod) ||
276-
(@override.Field != null && @override.Field == p.Field));
277-
if (baseProperty != null)
278-
return baseProperty;
279-
280-
baseProperty = GetBaseProperty(@base.Class, @override);
281-
if (baseProperty != null)
282-
return baseProperty;
283-
}
284-
return null;
285-
}
286-
287266
private static void RenameConflictingMethods(Class @class, Property property)
288267
{
289268
foreach (var method in @class.Methods.Where(

src/Generator/Passes/MultipleInheritancePass.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ private static void ImplementInterfaceProperties(Class @class, Class @interface)
247247
{
248248
var impl = CreateInterfaceProperty(property, @class);
249249
impl.OriginalNamespace = @interface;
250-
var rootBaseProperty = @class.GetBaseProperty(property, true);
250+
var rootBaseProperty = @class.GetBasePropertyByName(property, true);
251251
if (rootBaseProperty != null && rootBaseProperty.IsDeclared)
252252
impl.ExplicitInterfaceImpl = @interface;
253253
@class.Properties.Add(impl);

0 commit comments

Comments
 (0)