summaryrefslogtreecommitdiff
path: root/BCT/BytecodeTranslator
diff options
context:
space:
mode:
authorGravatar mikebarnett <unknown>2011-02-25 15:44:40 +0000
committerGravatar mikebarnett <unknown>2011-02-25 15:44:40 +0000
commita922ff73e833037aa49e0cdb149be63bba90484d (patch)
treed751487aeae99b284330ab91618111d93294ad34 /BCT/BytecodeTranslator
parent39e31c744fbc191b90db48459d898c6402605559 (diff)
Fixed dynamic dispatch so the most derived override is called for each subtype.
Diffstat (limited to 'BCT/BytecodeTranslator')
-rw-r--r--BCT/BytecodeTranslator/WholeProgram.cs27
1 files changed, 16 insertions, 11 deletions
diff --git a/BCT/BytecodeTranslator/WholeProgram.cs b/BCT/BytecodeTranslator/WholeProgram.cs
index 29b75d82..872466bb 100644
--- a/BCT/BytecodeTranslator/WholeProgram.cs
+++ b/BCT/BytecodeTranslator/WholeProgram.cs
@@ -114,8 +114,7 @@ namespace BytecodeTranslator {
Contract.Assert(!methodCall.IsStaticCall);
var resolvedMethod = methodCall.MethodToCall.ResolvedMethod;
Contract.Assert(!resolvedMethod.IsConstructor);
- List<IMethodReference> overrides = new List<IMethodReference>();
- FindOverrides(containingType, resolvedMethod, overrides);
+ var overrides = FindOverrides(containingType, resolvedMethod);
if (0 == overrides.Count) {
base.Visit(methodCall);
return;
@@ -195,9 +194,11 @@ namespace BytecodeTranslator {
Bpl.IfCmd ifcmd = null;
Contract.Assume(1 <= overrides.Count);
- foreach (var m in overrides) {
+ foreach (var typeMethodPair in overrides) {
+ var t = typeMethodPair.Item1;
+ var m = typeMethodPair.Item2;
var thenBranch = new Bpl.StmtListBuilder();
- methodname = TranslationHelper.CreateUniqueMethodName(m);
+ methodname = TranslationHelper.CreateUniqueMethodName(m); // REVIEW: Shouldn't this be call to FindOrCreateProcedure?
if (attrib != null)
call = new Bpl.CallCmd(token, methodname, inexpr, outvars, attrib);
else
@@ -206,7 +207,7 @@ namespace BytecodeTranslator {
ifcmd = new Bpl.IfCmd(token,
Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
this.sink.Heap.DynamicType(inexpr[0]),
- Bpl.Expr.Ident(this.sink.FindOrCreateType(m.ContainingType))
+ Bpl.Expr.Ident(this.sink.FindOrCreateType(t))
),
thenBranch.Collect(token),
null,
@@ -224,17 +225,21 @@ namespace BytecodeTranslator {
/// <summary>
/// Modifies <paramref name="overrides"/> as side-effect.
/// </summary>
- private void FindOverrides(ITypeReference type, IMethodDefinition resolvedMethod, List<IMethodReference> overrides) {
+ private List<Tuple<ITypeReference, IMethodReference>> FindOverrides(ITypeReference type, IMethodDefinition resolvedMethod) {
Contract.Requires(type != null);
Contract.Requires(resolvedMethod != null);
- Contract.Requires(overrides != null);
+ var overrides = new List<Tuple<ITypeReference, IMethodReference>>();
foreach (var subType in this.subTypes[type]) {
var overriddenMethod = MemberHelper.GetImplicitlyOverridingDerivedClassMethod(resolvedMethod, subType.ResolvedType);
- if (overriddenMethod != Dummy.Method)
- overrides.Add(overriddenMethod);
- if (this.subTypes.ContainsKey(subType))
- FindOverrides(subType, resolvedMethod, overrides);
+ if (overriddenMethod != Dummy.Method) {
+ resolvedMethod = overriddenMethod;
+ }
+ overrides.Add(Tuple.Create<ITypeReference, IMethodReference>(subType, resolvedMethod));
+ if (this.subTypes.ContainsKey(subType)) {
+ overrides.AddRange(FindOverrides(subType, resolvedMethod));
+ }
}
+ return overrides;
}
}