Пример #1
0
        private static void HandleNewArray(LocalOperation operation, StringBuilder bodySb,
                                           MidRepresentationVariables vars)
        {
            var assignment = (Assignment)operation.Value;
            var arrayData  = (NewArrayObject)assignment.Right;

            var assignedData = vars.GetVariableData(assignment.AssignedTo);

            switch (assignedData.Escaping)
            {
            case EscapingMode.Stack:
                bodySb.AppendFormat("Array <{1}> {0} ({2}); ",
                                    assignment.AssignedTo.Name,
                                    arrayData.TypeArray.ToCppName(),
                                    arrayData.ArrayLength.Name);
                break;

            default:
                bodySb.AppendFormat("{0} = std::make_shared< Array <{1}> >({2}); ",
                                    assignment.AssignedTo.Name,
                                    arrayData.TypeArray.ToCppName(),
                                    arrayData.ArrayLength.Name);
                break;
            }
        }
Пример #2
0
        private static void HandleAssign(StringBuilder sb, LocalOperation operation, MidRepresentationVariables vars,
                                         TypeDescriptionTable typeTable, MethodInterpreter interpreter)
        {
            var assignment = (Assignment)operation.Value;

            if (assignment.Right is NewConstructedObject)
            {
                HandleNewObject(operation, sb, vars, typeTable, interpreter);
                return;
            }
            var assignedTo    = assignment.AssignedTo;
            var localVariable = assignment.Right as LocalVariable;

            if (localVariable != null)
            {
                var leftVarType  = assignment.AssignedTo.ComputedType();
                var rightVarType = assignment.Right.ComputedType();
                if (leftVarType != rightVarType)
                {
                    if (rightVarType.ClrType.IsPointer)
                    {
                        sb.AppendFormat("{0} = *{1};", assignedTo, localVariable.Name);
                        return;
                    }
                }
                var assignedToData    = interpreter.AnalyzeProperties.GetVariableData(assignedTo);
                var localVariableData = interpreter.AnalyzeProperties.GetVariableData(localVariable);
                var rightVar          = localVariable;
                var description       = assignedTo.ComputedType();
                if (description.ClrTypeCode != TypeCode.Object ||
                    assignedToData == localVariableData)
                {
                    sb.AppendFormat("{0} = {1};", assignedTo.Name, rightVar.Name);
                    return;
                }
                switch (assignedToData)
                {
                case EscapingMode.Pointer:
                    switch (localVariableData)
                    {
                    case EscapingMode.Stack:
                        sb.AppendFormat("{0} = &{1};", assignedTo.Name, rightVar.Name);
                        return;

                    case EscapingMode.Smart:
                        sb.AppendFormat("{0} = ({1}).get();", assignedTo.Name, rightVar.Name);
                        return;
                    }
                    break;

                case EscapingMode.Smart:
                    throw new InvalidDataException("Case not possible!");
                }
                throw new InvalidDataException("Case not handled");
            }
            else
            {
                sb.AppendFormat("{0} = {1};", assignedTo.Name, assignment.Right.ComputedValue());
            }
        }
Пример #3
0
        private static void HandleNewObject(LocalOperation operation, StringBuilder bodySb,
                                            MidRepresentationVariables vars,
                                            TypeDescriptionTable typeTable, MethodInterpreter interpreter)
        {
            var value      = (Assignment)operation.Value;
            var rightValue = (NewConstructedObject)value.Right;
            var localValue = rightValue.Info;

            var declaringType = localValue.DeclaringType;
            var cppName       = declaringType.ToDeclaredVariableType(true, EscapingMode.Stack);
            var assignedData  = interpreter.AnalyzeProperties.GetVariableData(value.AssignedTo);
            var isStack       = assignedData == EscapingMode.Stack;

            if (isStack)
            {
                bodySb
                .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName);
            }
            else
            {
                bodySb.AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName);
            }
            bodySb.AppendLine();
            typeTable.SetIdOfInstance(bodySb, value.AssignedTo, declaringType, isStack);
        }
Пример #4
0
        private static void AddVariableContent(StringBuilder variablesSb, string format, LocalVariable localVariable,
                                               MidRepresentationVariables vars, MethodInterpreter interpreter)
        {
            var localVariableData = interpreter.AnalyzeProperties.GetVariableData(localVariable);

            if (localVariableData == EscapingMode.Stack)
            {
                return;
            }
            if (localVariable.ComputedType().ClrType.IsSubclassOf(typeof(MethodInfo)))
            {
                variablesSb
                .AppendFormat("void (*{0})({1});",
                              localVariable.Name,
                              ComputeCommaSeparatedParameterTypes(localVariable))
                .AppendLine();
                return;
            }
            if (localVariableData == EscapingMode.Pointer)
            {
                var cppName = localVariable.ComputedType()
                              .ClrType.ToDeclaredVariableType(true, localVariableData);
                variablesSb
                .AppendFormat(format, cppName, localVariable.Id)
                .AppendLine();
                return;
            }
            variablesSb
            .AppendFormat(format, localVariable.ComputedType()
                          .ClrType.ToDeclaredVariableType(true, localVariableData), localVariable.Id)
            .AppendLine();
        }
Пример #5
0
        static bool HandleCallOperations(MidRepresentationVariables vars, MethodInterpreter interpreter,
                                         ClosureEntities crRuntime, LocalOperation operation, CodeOutput bodySb)
        {
            switch (operation.Kind)
            {
            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, interpreter, crRuntime);
                break;

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

            default:
                return(false);
            }
            return(true);
        }
Пример #6
0
        static void OptimizeUnusedVregs(HashSet <int> vregConstants, MidRepresentationVariables variables)
        {
            if (vregConstants.Count == 0)
            {
                return;
            }
            var liveVRegs =
                variables.VirtRegs.Where(
                    vreg => vreg.Kind != VariableKind.Vreg || !vregConstants.Contains(vreg.Id)).ToList();

            variables.VirtRegs = liveVRegs;
        }
Пример #7
0
        private static void OptimizeUnusedLocals(HashSet <int> localConstants, MidRepresentationVariables variables)
        {
            if (localConstants.Count == 0)
            {
                return;
            }

            foreach (var localUnused in localConstants)
            {
                variables.LocalVars.RemoveAll(local => local.Id == localUnused);
            }
        }
Пример #8
0
        public static void HandleCallInterface(LocalOperation operation, StringBuilder sbCode,
                                               MidRepresentationVariables vars, MethodInterpreter interpreter, ClosureEntities crRuntime)
        {
            var operationData = (CallMethodStatic)operation;
            var sb            = new StringBuilder();
            var methodInfo    = operationData.Info.GetReversedMethod(crRuntime);
            var isVoidMethod  = methodInfo.GetReturnType().IsVoid();

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

            sb.AppendFormat("{0}_icall", methodInfo.ClangMethodSignature(crRuntime));
            WriteParametersToSb(operationData, sb, interpreter);

            sbCode.Append(sb);
        }
Пример #9
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);
        }
Пример #10
0
        public static void HandleCall(LocalOperation operation, StringBuilder sbCode, MidRepresentationVariables vars)
        {
            var operationData = (MethodData)operation.Value;
            var sb            = new StringBuilder();
            var methodInfo    = operationData.Info.GetReversedMethod();

            #region Write method name

            var isVoidMethod = methodInfo.GetReturnType().IsVoid();
            if (isVoidMethod)
            {
                sb.AppendFormat("{0}", methodInfo.ClangMethodSignature());
            }
            else
            {
                if (operationData.Result == null)
                {
                    sb.AppendFormat("{0}", methodInfo.ClangMethodSignature());
                }
                else
                {
                    sb.AppendFormat("{1} = {0}", methodInfo.ClangMethodSignature(),
                                    operationData.Result.Name);
                }
            }
            var identifierValues = operationData.Parameters;

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

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

            #endregion

            sb.Append("(");

            #region Parameters

            var pos           = 0;
            var isFirst       = true;
            var argumentTypes = operationData.Info.GetMethodArgumentTypes();
            foreach (var value in identifierValues)
            {
                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 = vars.GetVariableData(localValue);
                switch (localValueData.Escaping)
                {
                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

            sbCode.Append(sb);
        }
Пример #11
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);
        }
Пример #12
0
        static CodeOutput ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars,
                                        TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime)
        {
            var bodySb = new CodeOutput();

            foreach (var operation in operations)
            {
                bodySb.Append("\n");
                if (CppHandleOperators.HandleAssignmentOperations(bodySb, operation, operation.Kind, typeTable,
                                                                  interpreter, crRuntime))
                {
                    continue;
                }
                if (CppCastRelatedOperations.HandleCastRelatedOperations(typeTable, crRuntime, operation, bodySb,
                                                                         operation.Kind))
                {
                    continue;
                }
                if (HandleCallOperations(vars, interpreter, crRuntime, operation, bodySb))
                {
                    continue;
                }

                switch (operation.Kind)
                {
                case OperationKind.Label:
                    WriteLabel(bodySb, ((Label)operation).JumpTo);
                    break;

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

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

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

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

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

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


                default:
                    throw new InvalidOperationException(
                              $"Invalid operation '{operation.Kind}' is introduced in intermediary representation\nValue: {operation}");
                }
            }

            return(bodySb);
        }
Пример #13
0
        private static void HandleNewObject(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars)
        {
            var value      = (Assignment)operation.Value;
            var rightValue = (NewConstructedObject)value.Right;
            var localValue = rightValue.Info;

            var declaringType = localValue.DeclaringType;
            var cppName       = declaringType.ToDeclaredVariableType(true, EscapingMode.Stack);
            var assignedData  = vars.GetVariableData(value.AssignedTo);

            switch (assignedData.Escaping)
            {
            case EscapingMode.Stack:
                bodySb
                .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName)
                .AppendLine();
                break;

            default:
                bodySb
                .AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName)
                .AppendLine();;
                break;
            }
        }
Пример #14
0
        private static void HandleLoadField(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars)
        {
            var fieldGetterInfo  = (FieldGetter)operation.Value;
            var assignedFrom     = fieldGetterInfo.Instance;
            var assignedFromData = vars.GetVariableData(assignedFrom);
            var isOnStack        = assignedFromData.Escaping == EscapingMode.Stack;
            var fieldText        = String.Format(isOnStack ? "{0}.{1}" : "{0}->{1}", fieldGetterInfo.Instance.Name,
                                                 fieldGetterInfo.FieldName.ValidName());

            var assignedTo     = fieldGetterInfo.AssignedTo;
            var assignedToData = vars.GetVariableData(assignedTo);

            switch (assignedToData.Escaping)
            {
            case EscapingMode.Smart:
                bodySb.AppendFormat("{0} = {1};", assignedTo.Name, fieldText);
                break;

            case EscapingMode.Pointer:
                bodySb.AppendFormat("{0} = {1}.get();", assignedTo.Name, fieldText);
                break;
            }
        }
Пример #15
0
        private static void HandleReadArrayItem(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars)
        {
            var value        = (Assignment)operation.Value;
            var valueSrc     = (ArrayVariable)value.Right;
            var parentType   = valueSrc.Parent.ComputedType();
            var variableData = vars.GetVariableData(value.AssignedTo);

            switch (variableData.Escaping)
            {
            case EscapingMode.Smart:
                bodySb.AppendFormat(parentType.ClrType.IsClass
                        ? "{0} = (*{1})[{2}];"
                        : "{0} = {1}[{2}];",
                                    value.AssignedTo.Name, valueSrc.Parent.Name, valueSrc.Index.Name);
                return;

            case EscapingMode.Pointer:
                bodySb.AppendFormat(parentType.ClrType.IsClass
                        ? "{0} = ((*{1})[{2}]).get();"
                        : "{0} = ({1}[{2}]).get();",
                                    value.AssignedTo.Name, valueSrc.Parent.Name, valueSrc.Index.Name);

                return;
            }
        }
Пример #16
0
        public static bool HandleAssignmentOperations(MidRepresentationVariables vars, StringBuilder bodySb, LocalOperation operation, OperationKind kind)
        {
            switch (kind)
            {
            case OperationKind.Assignment:
                HandleAssign(bodySb, operation, vars);
                break;

            case OperationKind.BinaryOperator:
                HandleOperator(operation.Value, bodySb);
                break;

            case OperationKind.UnaryOperator:
                HandleUnaryOperator((UnaryOperator)operation.Value, bodySb);
                break;

            case OperationKind.SetField:
                HandleSetField(operation, bodySb);
                break;

            case OperationKind.GetField:
                HandleLoadField(operation, bodySb, vars);
                break;

            case OperationKind.SetStaticField:
                HandleSetStaticField(operation, bodySb);
                break;

            case OperationKind.GetStaticField:
                HandleLoadStaticField(operation, bodySb);
                break;

            case OperationKind.GetArrayItem:
                HandleReadArrayItem(operation, bodySb, vars);
                break;

            case OperationKind.NewObject:
                HandleNewObject(operation, bodySb, vars);
                break;

            case OperationKind.NewArray:
                HandleNewArray(operation, bodySb, vars);
                break;

            case OperationKind.AddressOfArrayItem:
                HandleGetAddressOfArrayItem(operation, bodySb);
                break;

            case OperationKind.RefAssignment:
                HandleRefAssignment(operation, bodySb);
                break;

            case OperationKind.DerefAssignment:
                HandleDerefAssignment(operation, bodySb);
                break;

            case OperationKind.FieldRefAssignment:
                HandleFieldRefAssignment(operation, bodySb);
                break;

            case OperationKind.LoadFunction:
                HandleLoadFunction(operation, bodySb);
                break;

            case OperationKind.SizeOf:
                HandleSizeOf(operation, bodySb);
                break;

            default:
                return(false);
            }
            return(true);
        }
Пример #17
0
        private static StringBuilder ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars,
                                                   TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime)
        {
            var bodySb = new StringBuilder();

            foreach (var operation in operations)
            {
                if (CppHandleOperators.HandleAssignmentOperations(bodySb, operation, operation.Kind, typeTable,
                                                                  interpreter, crRuntime))
                {
                    bodySb.AppendLine();
                    continue;
                }
                switch (operation.Kind)
                {
                case OperationKind.Label:
                    WriteLabel(bodySb, ((Label)operation).JumpTo);
                    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, interpreter, crRuntime);
                    break;

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

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

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

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

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

                case OperationKind.Box:
                    var boxing = crRuntime.FindFeature("Boxing");
                    if (!boxing.IsUsed)
                    {
                        boxing.IsUsed = true;
                        boxing.Declarations.Add(@"template<class T>
struct BoxedT : public System_Object
{
	T Data;
};

template<class T>
std::shared_ptr<System_Object> box_value(T value, int typeId){
	auto result = std::make_shared<BoxedT< T > >();
	result->_typeId = typeId;
	result->Data = value;
	return result;
}

template<class T>
T unbox_value(std::shared_ptr<System_Object> value){
	auto resultObject = value.get();
	auto castedUnboxing = (BoxedT<T>*)resultObject;
	return castedUnboxing->Data;
}");
                    }
                    HandleBox((Boxing)operation, bodySb, typeTable, crRuntime);
                    break;

                case OperationKind.CastClass:
                    HandleCastClass((ClassCasting)operation, bodySb, crRuntime);
                    break;

                case OperationKind.Unbox:
                    HandleUnbox((Unboxing)operation, bodySb, crRuntime);
                    break;

                case OperationKind.IsInstance:

                    HandleIsInstance((IsInstance)operation, bodySb, crRuntime);
                    break;

                default:
                    throw new InvalidOperationException(
                              string.Format(
                                  "Invalid operation '{0}' is introduced in intermediary representation\nValue: {1}",
                                  operation.Kind,
                                  operation));
                }
                bodySb.AppendLine();
            }
            bodySb.AppendLine("}");
            return(bodySb);
        }