static bool HandleInterpreterInstructions(CilMethodInterpreter interpreter, ClosureEntities closure) { var useDef = interpreter.MidRepresentation.UseDef; var calls = useDef.GetOperationsOfKind(OperationKind.CallVirtual).ToArray(); var allOps = useDef.GetLocalOperations(); var result = false; foreach (var callOp in calls) { var op = allOps[callOp]; var methodData = (CallMethodStatic)op; var thisParameter = (LocalVariable)methodData.Parameters.First(); var clrType = thisParameter.FixedType.GetClrType(closure); var overridenTypes = clrType.ImplementorsOfT(closure); overridenTypes.Remove(clrType); //Check for NewSlot if (clrType.BaseType != null && !methodData.Info.IsVirtual) { if ( clrType.BaseType.GetMethods(ClosureEntitiesBuilder.AllFlags) .Select(m => m.MethodMatches(methodData.Info)) .Any()) { continue; } } if (overridenTypes.Count >= 1) { continue; } //TODO: map correct method var resolvedMethod = AddVirtualMethodImplementations.GetImplementingMethod(clrType, (MethodInfo)methodData.Info); methodData.Interpreter = closure.ResolveMethod(resolvedMethod); interpreter.MidRepresentation.LocalOperations[callOp] = new CallMethodStatic(methodData.Interpreter) { Result = methodData.Result, Parameters = methodData.Parameters }; result = true; } if (result) { interpreter.MidRepresentation.UpdateUseDef(); } return(result); }
public static string GenerateTypeTableCode(TypeDescriptionTable table, ClosureEntities crRuntime) { var sb = new StringBuilder(); sb.AppendLine("// --- Begin definition of virtual implementingMethod tables ---"); sb.AppendLine("System_Void setupTypeTable();") .AppendLine(); var vcalls = crRuntime.AbstractMethods; WriteForwardVcalls(crRuntime, vcalls, sb); foreach (var virtualMethod in vcalls) { var methodName = virtualMethod.ClangMethodSignature(crRuntime); var parametersString = GetParametersString(virtualMethod, crRuntime); sb.Append(virtualMethod.ReturnType.ToCppName(EscapingMode.Smart)); sb.Append(" "); sb.Append(methodName); sb.Append("_vcall("); sb.AppendFormat(parametersString); sb.AppendLine(") {"); sb.AppendLine("switch (_this->_typeId)").AppendLine("{"); var declaringType = virtualMethod.DeclaringType; var implementingTypes = declaringType.ImplementorsOfT(crRuntime);//.MappedTypes.Values); foreach (var implementingType in implementingTypes) { if (implementingType.GetReversedMappedType(crRuntime) != implementingType) { continue; } var implementingMethod = AddVirtualMethodImplementations.GetImplementingMethod(implementingType, virtualMethod); // if (implementingMethod == null) //We should call the next implementingMethod in line ... not ignore this object // continue; if (implementingMethod != null) { if (implementingMethod.GetMethodBody() == null) { continue; } var declaringTypeImplementation = implementingMethod.DeclaringType.GetReversedMappedType(crRuntime); var typeId = table.GetTypeId(declaringTypeImplementation); sb.AppendFormat("case {0}:", typeId).AppendLine(); var isVoid = virtualMethod.ReturnType == typeof(void); if (!isVoid) { sb.Append("return "); } var methodImpl = implementingMethod.ClangMethodSignature(crRuntime); var parametersCallString = GetCall(virtualMethod, implementingMethod, crRuntime); sb .AppendFormat("{0}(", methodImpl) .AppendFormat("{0});", parametersCallString) .AppendLine(); if (isVoid) { sb.Append("return;").AppendLine(); } } else { var typeId = table.GetTypeId(implementingType.GetReversedMappedType(crRuntime)); sb.AppendFormat("case {0}:", typeId).AppendLine(); var isVoid = virtualMethod.ReturnType == typeof(void); if (!isVoid) { sb.Append("return "); } var method = implementingType.GetMethod(virtualMethod.Name, virtualMethod.GetParameters().Select(j => j.ParameterType).ToArray()); var methodImpl = method.ClangMethodSignature(crRuntime); var parametersCallString = GetCall(virtualMethod, method, crRuntime); sb .AppendFormat("{0}(", methodImpl) .AppendFormat("{0});", parametersCallString) .AppendLine(); if (isVoid) { sb.Append("return;").AppendLine(); } } } sb.AppendLine("} //switch"); sb.AppendLine("}"); } return(sb.ToString()); }