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);
        }
示例#2
0
        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());
        }