Exemplo n.º 1
0
        private static void WriteClosureStructBodies(Type[] typeDatas, StringBuilder sb, CrRuntimeLibrary crRuntime)
        {
            foreach (var typeData in typeDatas)
            {
                var mappedType = typeData.GetMappedType();
                if (!mappedType.IsGenericType)
                {
                    sb.AppendFormat("struct {0}; ", mappedType.ToCppMangling()).AppendLine();
                }
            }
            foreach (var typeData in typeDatas)
            {
                if (DelegateManager.IsTypeDelegate(typeData))
                {
                    continue;
                }
                var type       = typeData.GetMappedType();
                var mappedType = typeData;

                if (mappedType.IsGenericType)
                {
                    var genericTypeCount = mappedType.GetGenericArguments().Length;
                    var typeNames        = new List <string>();
                    for (var i = 1; i <= genericTypeCount; i++)
                    {
                        typeNames.Add("class T" + i);
                    }
                    sb.AppendFormat("template <{0}> ", string.Join(", ", typeNames)).AppendLine();
                }
                if (!type.IsValueType && type.BaseType != null)
                {
                    sb.AppendFormat("struct {0} : public {1} {{", type.ToCppMangling(), type.BaseType.ToCppMangling());
                }
                else
                {
                    sb.AppendFormat("struct {0} {{", type.ToCppMangling());
                }
                sb.AppendLine();
                if (type == typeof(object))
                {
                    sb.AppendLine("int _typeId;");
                }
                WriteClassFieldsBody(sb, mappedType, crRuntime);
                sb.AppendFormat("}};").AppendLine();

                var typedesc = UsedTypeList.Set(type, crRuntime);
                typedesc.WriteStaticFieldInitialization(sb);
            }
        }
Exemplo n.º 2
0
        public static Dictionary <int, bool> EscapingParameterData(this MethodBase info, CrRuntimeLibrary crRuntime)
        {
            var interpreter = info.GetInterpreter(crRuntime);

            if (interpreter == null)
            {
                return(null);
            }
            var calledMethod    = interpreter.MidRepresentation;
            var otherMethodData = (Dictionary <int, bool>)calledMethod.GetAdditionalProperty(EscapeName);

            if (otherMethodData == null)
            {
                return(null);
            }
            return(otherMethodData);
        }
Exemplo n.º 3
0
        private static StringBuilder ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars,
                                                   TypeDescriptionTable typeTable, MethodInterpreter interpreter, CrRuntimeLibrary crRuntime)
        {
            var bodySb = new StringBuilder();

            foreach (var operation in operations)
            {
                if (CppHandleOperators.HandleAssignmentOperations(vars, bodySb, operation, operation.Kind, typeTable,
                                                                  interpreter))
                {
                    bodySb.AppendLine();
                    continue;
                }
                switch (operation.Kind)
                {
                case OperationKind.Label:
                    WriteLabel(bodySb, (int)operation.Value);
                    break;

                case OperationKind.AlwaysBranch:
                    HandleAlwaysBranchOperator(operation, bodySb);
                    break;

                case OperationKind.BranchOperator:
                    CppHandleBranches.HandleBranchOperator(operation, bodySb);
                    break;

                case OperationKind.Call:
                    CppHandleCalls.HandleCall(operation, bodySb, vars, interpreter, crRuntime);
                    break;

                case OperationKind.CallInterface:
                    CppHandleCalls.HandleCallInterface(operation, bodySb, vars, interpreter, crRuntime);
                    break;

                case OperationKind.CallVirtual:
                    CppHandleCalls.HandleCallVirtual(operation, bodySb, vars, interpreter, crRuntime);
                    break;

                case OperationKind.CallRuntime:
                    CppHandleCalls.HandleCallRuntime(operation, bodySb);
                    break;

                case OperationKind.Return:
                    CppHandleCalls.HandleReturn(operation, bodySb);
                    break;

                case OperationKind.CopyArrayInitializer:
                    HandleCopyArrayInitializer(operation, bodySb);
                    break;

                case OperationKind.Switch:
                    HandleSwitch(operation, bodySb);
                    break;

                case OperationKind.Comment:
                    HandleComment(operation.Value.ToString(), bodySb);
                    break;

                default:
                    throw new InvalidOperationException(
                              string.Format(
                                  "Invalid operation '{0}' is introduced in intermediary representation\nValue: {1}",
                                  operation.Kind,
                                  operation.Value));
                }
                bodySb.AppendLine();
            }
            bodySb.AppendLine("}");
            return(bodySb);
        }
        public static bool ReadPurity(MethodBase methodBase, CrRuntimeLibrary crRuntime)
        {
            var method = methodBase.GetInterpreter(crRuntime);

            return(AnalyzeFunctionPurity.ReadPurity(method));
        }
Exemplo n.º 5
0
        public static MethodInterpreter GetInterpreter(this MethodData methodData, CrRuntimeLibrary crRuntime)
        {
            var methodBase = methodData.Info;

            return(GetInterpreter(methodBase, crRuntime));
        }
Exemplo n.º 6
0
        public static void SortTypeClosure(List <Type> types, CrRuntimeLibrary crRuntime)
        {
            var typeComparer = new ClosureTypeComparer(types, crRuntime);

            typeComparer.Sort();
        }
        public static void RemoveCandidatesIfEscapes(LocalVariable localVariable,
                                                     HashSet <LocalVariable> candidateVariables, LocalOperation op, CrRuntimeLibrary crRuntime)
        {
            switch (op.Kind)
            {
            case OperationKind.Assignment:
                HandleAssign(candidateVariables, op);
                break;

            case OperationKind.Return:
                HandleReturn(localVariable, candidateVariables, op);
                break;

            case OperationKind.Call:
            case OperationKind.CallVirtual:
            case OperationKind.CallInterface:
                HandleCall(localVariable, candidateVariables, op, crRuntime);
                break;

            case OperationKind.BinaryOperator:
            case OperationKind.UnaryOperator:
            case OperationKind.BranchOperator:
            case OperationKind.GetArrayItem:
            case OperationKind.GetField:
                break;

            case OperationKind.SetArrayItem:
                HandleSetArrayItem(candidateVariables, op);
                break;

            case OperationKind.SetField:
                HandleSetArrayItem(candidateVariables, op);
                break;

            case OperationKind.RefAssignment:
                HandleRefAssignment(localVariable, candidateVariables, op);
                break;

            case OperationKind.FieldRefAssignment:
                break;

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 8
0
 private static void HandleLoadFunctionInstructions(Dictionary <MethodInterpreterKey, MethodInterpreter> result,
                                                    LocalOperation[] localOperations, List <MethodInterpreter> toAdd, CrRuntimeLibrary crRuntime)
 {
     if (localOperations.Length == 0)
     {
         return;
     }
     foreach (var localOperation in localOperations)
     {
         var functionPointer = (FunctionPointerStore)localOperation.Value;
         var info            = functionPointer.FunctionPointer;
         var interpreter     = info.GetInterpreter(crRuntime);
         if (interpreter == null)
         {
             continue;
         }
         result[interpreter.ToKey()] = interpreter;
         toAdd.Add(interpreter);
     }
 }
Exemplo n.º 9
0
 public static List <MethodInterpreter> GetMethodClosure(this MethodInterpreter entryPoints,
                                                         CrRuntimeLibrary crRuntime)
 {
     return(GetClosureDictionary(entryPoints, crRuntime).Values.ToList());
 }
Exemplo n.º 10
0
        public static void HandleCallVirtual(LocalOperation operation, StringBuilder sbCode,
                                             MidRepresentationVariables vars, MethodInterpreter interpreter, CrRuntimeLibrary crRuntime)
        {
            var operationData = (MethodData)operation.Value;
            var sb            = new StringBuilder();
            var methodInfo    = operationData.Info.GetReversedMethod();
            var isVoidMethod  = methodInfo.GetReturnType().IsVoid();

            if (!isVoidMethod && operationData.Result != null)
            {
                sb.AppendFormat("{0} = ", operationData.Result.Name);
            }

            sb.AppendFormat("{0}_vcall", methodInfo.ClangMethodSignature());

            if (WriteParametersToSb(operationData, methodInfo, sb, interpreter, crRuntime))
            {
                return;
            }

            sbCode.Append(sb);
        }
Exemplo n.º 11
0
 public static Type ReversedType(this Type type, CrRuntimeLibrary crRuntime)
 {
     return(crRuntime.GetReverseType(type) ?? type);
 }
Exemplo n.º 12
0
        private static bool WriteParametersToSb(MethodData operationData, MethodBase methodInfo, StringBuilder sb,
                                                MethodInterpreter interpreter, CrRuntimeLibrary crRuntime)
        {
            var identifierValues = operationData.Parameters;

            var escapingData = methodInfo.BuildEscapingBools(crRuntime);

            if (escapingData == null)
            {
                var argumentsCall = String.Join(", ", identifierValues.Select(p =>
                {
                    var computeValue = p.ComputedValue();

                    return(computeValue);
                }));

                sb.AppendFormat("({0});", argumentsCall);
                return(true);
            }

            #region Parameters

            sb.Append("(");
            var pos            = 0;
            var isFirst        = true;
            var argumentUsages =
                operationData.Interpreter.AnalyzeProperties.GetUsedArguments(
                    operationData.Interpreter.MidRepresentation.Vars.Arguments);

            var argumentTypes = operationData.Info.GetMethodArgumentTypes();
            for (var index = 0; index < identifierValues.Count; index++)
            {
                var value = identifierValues[index];
                if (!argumentUsages[index])
                {
                    continue;
                }
                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    sb.Append(", ");
                }
                var localValue   = value as LocalVariable;
                var argumentData = argumentTypes[pos];
                var isEscaping   = escapingData[pos];
                pos++;
                if (localValue == null)
                {
                    sb.Append(value.ComputedValue());
                    continue;
                }
                if (localValue.Kind == VariableKind.Argument)
                {
                }

                if (localValue.ComputedType().ClrType == typeof(IntPtr))
                {
                    var argumentTypeCast = argumentData.ToCppMangling();
                    sb.AppendFormat("({0}){1}", argumentTypeCast, localValue.Name);
                    continue;
                }

                var localValueData = interpreter.AnalyzeProperties.GetVariableData(localValue);
                switch (localValueData)
                {
                case EscapingMode.Smart:
                    if (!isEscaping && localValue.ComputedType().ClrType.IsClass)
                    {
                        sb.AppendFormat("{0}.get()", localValue.Name);
                    }
                    else
                    {
                        sb.AppendFormat("{0}", localValue.Name);
                    }
                    continue;

                case EscapingMode.Stack:
                    sb.AppendFormat("&{0}", localValue.Name);
                    continue;

                case EscapingMode.Pointer:
                    sb.AppendFormat(!isEscaping ? "{0}" : "{0}.get()", localValue.Name);
                    continue;
                }
            }

            sb.Append(");");

            #endregion

            return(false);
        }
Exemplo n.º 13
0
        public static HashSet <Type> GetTypesClosure(List <MethodInterpreter> methodList, out bool foundNewMethods,
                                                     ProgramClosure programClosure, CrRuntimeLibrary crRuntime)
        {
            var typesSet = ScanMethodParameters(methodList, crRuntime);

            //For struct types we need to add them separately
            foreach (var methodInterpreter in methodList)
            {
                foreach (var operation in methodInterpreter.MidRepresentation.LocalOperations)
                {
                    if (operation is Assignment)
                    {
                        var type = (operation as Assignment).AssignedTo.FixedType.ClrType;
                        if (!typesSet.Contains(type) && !type.IsByRef)
                        {
                            typesSet.Add(type);
                        }
                    }
                    if (operation is RefAssignment)
                    {
                        var type = (operation as RefAssignment).Left.FixedType.ClrType;
                        if (!typesSet.Contains(type) && !type.IsByRef)
                        {
                            typesSet.Add(type);
                        }
                    }
                }
            }

            foundNewMethods = false;

            var resultTypes = BuildScannedDictionaryFromTypesAndInstructions(typesSet, crRuntime);
            var methodDict  = methodList.ToDictionary(method => method.Method.Register(crRuntime).ToKey());
            var virtMethods = methodList.Where(m => m.Method.IsVirtual).ToArray();

            foreach (var virt in virtMethods)
            {
                var baseClass  = virt.Method.DeclaringType;
                var methodName = virt.Method.Name;
                var methodArgs = virt.Method.GetParameters().Select(par => par.ParameterType).ToArray();
                foreach (var type in resultTypes)
                {
                    var hasinterface = false;//TODO: for some reason I cannot use .Contains / Linq here ?
                    foreach (var @interface in type.GetInterfaces())
                    {
                        if (@interface == baseClass)
                        {
                            hasinterface = true;
                            //   methodName = baseClass.Name +"."+methodName;
                            break;
                        }
                    }
                    if ((!(type.IsSubclassOf(baseClass) || hasinterface)))
                    {
                        continue;
                    }
                    MethodInfo implMethod;
                    if (!hasinterface)
                    {
                        implMethod = type.GetMethod(methodName, methodArgs);
                    }
                    else
                    {
                        implMethod =
                            type.GetInterfaceMap(baseClass)
                            .InterfaceMethods.Where(m => m.Name == methodName && (!m.GetParameters().Select(j => j.ParameterType).Except(methodArgs).Any())).FirstOrDefault();
                    }
                    if (methodDict.ContainsKey(implMethod.Register(crRuntime).ToKey()))
                    {
                        continue;
                    }
                    var implInterpreter = implMethod.Register();
                    MetaLinker.Interpret(implInterpreter, crRuntime);
                    methodList.Add(implInterpreter);
                    foundNewMethods = true;
                }
            }
            return(resultTypes);
        }
Exemplo n.º 14
0
        private static HashSet <Type> ScanMethodParameters(List <MethodInterpreter> closure, CrRuntimeLibrary crRuntime)
        {
            var typesSet = new HashSet <Type>();

            foreach (var interpreter in closure)
            {
                var method = interpreter.Method;
                foreach (var parameter in method.GetParameters())
                {
                    var parameterType = parameter.ParameterType;

                    if (parameterType.IsSubclassOf(typeof(Array)))
                    {
                        continue;
                    }
                    if (parameterType.IsByRef)
                    {
                        parameterType = parameterType.GetElementType();
                    }
                    typesSet.Add(parameterType.GetReversedType(crRuntime));
                }
                typesSet.Add(method.DeclaringType.GetReversedType(crRuntime));
            }
            return(typesSet);
        }
Exemplo n.º 15
0
        private static void WriteClassFieldsBody(StringBuilder sb, Type mappedType, CrRuntimeLibrary crRuntime)
        {
            var typeDesc = UsedTypeList.Set(mappedType, crRuntime);

            typeDesc.WriteLayout(sb);
        }
Exemplo n.º 16
0
        public static void UpdateMethodEntryClosure(MethodInterpreter entryPoint,
                                                    Dictionary <MethodInterpreterKey, MethodInterpreter> result, CrRuntimeLibrary crRuntime)
        {
            var useDef = entryPoint.MidRepresentation.UseDef;

            entryPoint.MidRepresentation.UpdateUseDef();
            var ops      = useDef.GetLocalOperations();
            var callList = useDef.GetOperationsOfKind(OperationKind.Call).ToList();

            callList.AddRange(useDef.GetOperationsOfKind(OperationKind.CallVirtual));
            callList.AddRange(useDef.GetOperationsOfKind(OperationKind.CallInterface));
            var localOperations = callList.Select(i => ops[i]).ToArray();
            var toAdd           = HandleCallInstructions(result, localOperations, crRuntime);
            var funcList        = useDef.GetOperationsOfKind(OperationKind.LoadFunction).ToList();

            localOperations = funcList.Select(i => ops[i]).ToArray();
            HandleLoadFunctionInstructions(result, localOperations, toAdd, crRuntime);

            HandleTypeInitializers(result, toAdd, crRuntime);

            HandleGenerics(result, toAdd, crRuntime);
        }
Exemplo n.º 17
0
        public static StringBuilder GenerateSourceStringBuilder(MethodInterpreter interpreter, List <Type> typeClosure,
                                                                List <MethodInterpreter> closure,
                                                                VirtualMethodTable typeTable, CrRuntimeLibrary crRuntime)
        {
            var sb = new StringBuilder();

            sb.AppendLine("#include \"sloth.h\"");

            var virtualMethodTableCodeWriter = new VirtualMethodTableCodeWriter(typeTable, closure);

            WriteClosureStructBodies(typeClosure.ToArray(), sb, crRuntime);
            WriteClosureDelegateBodies(closure, sb);
            WriteClosureHeaders(closure, sb, crRuntime);

            sb.AppendLine("#include \"runtime_base.hpp\"");

            sb.AppendLine(virtualMethodTableCodeWriter.GenerateTypeTableCode());
            WriteCppMethods(closure, sb);
            WriteClosureMethods(closure, sb, typeTable.TypeTable, crRuntime);

            WriteMainBody(interpreter, sb);
            sb.AppendLine(PlatformInvokeCodeWriter.LoadDllMethods());
            sb.AppendLine(ConstByteArrayList.BuildConstantTable());
            sb.AppendLine(LinkingData.Instance.Strings.BuildStringTable());

            return(sb);
        }
Exemplo n.º 18
0
        private static HashSet <Type> BuildScannedDictionaryFromTypesAndInstructions(HashSet <Type> typesSet,
                                                                                     CrRuntimeLibrary crRuntime)
        {
            bool isAdded;

            do
            {
                var toAdd = new HashSet <Type>(typesSet);
                foreach (var type in typesSet)
                {
                    AddBaseTypesToHash(type, toAdd);
                    var mappedType = crRuntime.GetMappedType(type);
                    if (type.IsPrimitive)
                    {
                        continue;
                    }

                    var fieldTypes = UsedTypeList.GetFieldTypeDependencies(type);
                    toAdd.AddRange(fieldTypes);
                    var fields = mappedType.GetFields().ToList();

                    fields.AddRange(mappedType.GetFields(
                                        BindingFlags.NonPublic
                                        | BindingFlags.Instance
                                        | BindingFlags.Static));
                    foreach (var fieldInfo in fields)
                    {
                        var fieldType = fieldInfo.FieldType;
                        if (fieldType.IsInterface)
                        {
                            continue;
                        }
                        if (fieldType.IsSubclassOf(typeof(Array)))
                        {
                            fieldType = fieldType.GetElementType();
                        }
                        if (fieldType.IsPointer || fieldType.IsByRef)
                        {
                            fieldType = fieldType.GetElementType();
                        }

                        var typeDesc = UsedTypeList.Set(type, crRuntime);
                        if (typeDesc == null)
                        {
                            continue;
                        }
                        toAdd.Add(fieldType);
                        AddBaseTypesToHash(fieldType, toAdd);
                    }
                }
                isAdded  = (toAdd.Count != typesSet.Count);
                typesSet = toAdd;
            } while (isAdded);
            var typesClosure = typesSet.Where(t =>
                                              IsRefClassType(t) && !t.IsInterface).ToList();

            foreach (var type in typesClosure)
            {
                UsedTypeList.Set(type, crRuntime);
            }

            typesSet.Remove(typeof(void));
            typesSet.Remove(typeof(IntPtr));
            typesSet.Remove(typeof(Array));

            // typesSet.RemoveWhere(t => t.IsInterface); Interfaces should be treated as classes
            typesSet.RemoveWhere(t => t.IsPrimitive);
            typesSet.RemoveWhere(t => t.IsSubclassOf(typeof(Array)));
            typesSet.RemoveWhere(t => t.GetMappedType() == t && string.IsNullOrEmpty(t.FullName));
            return(typesSet);
        }