private static void AllocateVariablesOnStack(LocalOperation[] localOp, HashSet <LocalVariable> candidateVariables,
                                                     MethodInterpreter interpreter)
        {
            var newOps = localOp.Where(op =>
                                       op.Kind == OperationKind.NewArray ||
                                       op.Kind == OperationKind.NewObject).ToArray();

            if (newOps.Length == 0)
            {
                return;
            }
            foreach (var op in newOps)
            {
                var variable = op.GetDefinition();
                if (variable == null)
                {
                    continue;
                }

                if (!candidateVariables.Contains(variable))
                {
                    continue;
                }
                var variableData = interpreter.AnalyzeProperties.GetVariableData(variable);

                interpreter.AnalyzeProperties.SetVariableData(variable, EscapingMode.Stack);
            }
        }
Пример #2
0
        public MethodData(MethodInterpreter interpreter)
        {
            Parameters = new List <IdentifierValue>();

            Interpreter = interpreter;
            Info        = interpreter.Method;
        }
Пример #3
0
        public void WriteCodeToOutput(CodeOutput bodySb, MethodInterpreter interpreter)
        {
            bodySb.Append("\n");

            if (Returning == null)
            {
                bodySb.Append("return;");
            }
            else
            {
                //Need to expand this for more cases
                if (Returning is ConstValue)
                {
                    var retType = interpreter.Method.GetReturnType();
                    if (retType == typeof(string))
                    {
                        bodySb.AppendFormat("return {0};", Returning.ComputedValue());
                    }
                    else
                    {
                        bodySb.AppendFormat("return {0};", Returning.Name);
                    }
                }
                else
                {
                    bodySb.AppendFormat("return {0};", Returning.Name);
                }
            }
        }
Пример #4
0
        public override void OptimizeOperations(MethodInterpreter interpreter)
        {
            var useDef     = interpreter.MidRepresentation.UseDef;
            var operations = useDef.GetLocalOperations();

            var labelTable = useDef.GetLabelTable(true);
            var reached    = new SortedSet <int>();

            Interpret(0, operations, labelTable, reached);
            if (reached.Count == operations.Length)
            {
                return;
            }
            Result = true;
            var toDelete = new List <int>();

            for (var i = 0; i < operations.Length; i++)
            {
                if (!reached.Contains(i))
                {
                    toDelete.Add(i);
                }
            }
            interpreter.DeleteInstructions(toDelete);
        }
Пример #5
0
        private static void HandleReadArrayItem(LocalOperation operation, StringBuilder bodySb,
                                                MethodInterpreter interpreter)
        {
            var value        = (Assignment)operation.Value;
            var valueSrc     = (ArrayVariable)value.Right;
            var parentType   = valueSrc.Parent.ComputedType();
            var variableData = interpreter.AnalyzeProperties.GetVariableData(value.AssignedTo);

            switch (variableData)
            {
            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;
            }
        }
Пример #6
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);
        }
Пример #7
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());
            }
        }
        public override void OptimizeOperations(MethodInterpreter interpreter)
        {
            var midRepresentation = interpreter.MidRepresentation;
            var useDef            = midRepresentation.UseDef;
            var operations        = useDef.GetLocalOperations();
            var localOps          = midRepresentation.LocalOperations;
            var callIndices       = useDef.GetOperationsOfKind(OperationKind.Call);

            foreach (var index in callIndices)
            {
                var op         = operations[index];
                var methodData = (MethodData)op.Value;
                var info       = methodData.Info;
                if (!info.IsConstructor)
                {
                    continue;
                }
                if (info.DeclaringType != typeof(object) &&
                    info.DeclaringType != interpreter.Method.DeclaringType)
                {
                    continue;
                }
                if (methodData.Interpreter.MidRepresentation.LocalOperations.Count > 1)
                {
                    continue;
                }
                localOps.RemoveAt(index);
                Result = true;
                return;
            }
        }
Пример #9
0
        private void HandleInterpreterInstructions(MethodInterpreter interpreter,
                                                   List <MethodInterpreter> methodInterpreters, List <Type> usedTypes)
        {
            var useDef = interpreter.MidRepresentation.UseDef;
            var calls  = useDef.GetOperationsOfKind(OperationKind.CallVirtual).ToList();
            var allOps = useDef.GetLocalOperations();

            foreach (var callOp in calls)
            {
                var op                    = allOps[callOp];
                var methodData            = (MethodData)op.Value;
                var callingInterpreterKey = methodData.Interpreter.ToKey();
                var declaringType         = callingInterpreterKey.Interpreter.DeclaringType;
                var implementors          = declaringType.ClrType.ImplementorsOfT(usedTypes);
                if (implementors.Count > 0)
                {
                    continue;
                }
                op.Kind = OperationKind.Call;
                Result  = true;
            }
            if (Result)
            {
                interpreter.MidRepresentation.UpdateUseDef();
            }
        }
Пример #10
0
        /// <inheritdoc/>
        internal override object Run()
        {
            var declarations = BaZicInterpreter.MethodDeclarations.Where(m => string.Compare(m.Name.Identifier, Expression.MethodName.Identifier, StringComparison.Ordinal) == 0);

            if (declarations.Count() == 0)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedMethodNotFound(Expression.MethodName)), Expression);
                return(null);
            }
            else if (declarations.Count() > 1)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedSeveralMethods(Expression.MethodName)), Expression);
                return(null);
            }

            // If the invocation is made manually by the user (outisde of the execution flow).
            if (_failIfNotExtern)
            {
                if (!declarations.Single().IsExtern)
                {
                    BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedMethodNotFound(Expression.MethodName)), Expression);
                    return(null);
                }

                if (!declarations.Single().IsAsync&& Expression.Await)
                {
                    Expression.Await = false;
                }
            }

            var methodInterpreter = new MethodInterpreter(BaZicInterpreter, ParentInterpreter, declarations.Single(), Expression, _executionFlowId);

            return(methodInterpreter.Invoke());
        }
Пример #11
0
        public static HashSet <LocalVariable> GetAllUsedVariables(MethodInterpreter interpreter,
                                                                  bool includeDefinitions = false)
        {
            var useDef = interpreter.MidRepresentation.UseDef;

            return(GetAllUsedVariables(useDef, includeDefinitions));
        }