Exemplo n.º 1
0
        internal static DkmCompiledClrInspectionQuery ToQueryResult(
            this CompileResult compResult,
            DkmCompilerId languageId,
            ResultProperties resultProperties,
            DkmClrRuntimeInstance runtimeInstance)
        {
            if (compResult == null)
            {
                return(null);
            }

            Debug.Assert(compResult.Assembly != null);
            Debug.Assert(compResult.TypeName != null);
            Debug.Assert(compResult.MethodName != null);

            ReadOnlyCollection <byte> customTypeInfo;
            Guid customTypeInfoId = compResult.GetCustomTypeInfo(out customTypeInfo);

            return(DkmCompiledClrInspectionQuery.Create(
                       runtimeInstance,
                       Binary: new ReadOnlyCollection <byte>(compResult.Assembly),
                       DataContainer: null,
                       LanguageId: languageId,
                       TypeName: compResult.TypeName,
                       MethodName: compResult.MethodName,
                       FormatSpecifiers: compResult.FormatSpecifiers,
                       CompilationFlags: resultProperties.Flags,
                       ResultCategory: resultProperties.Category,
                       Access: resultProperties.AccessType,
                       StorageType: resultProperties.StorageType,
                       TypeModifierFlags: resultProperties.ModifierFlags,
                       CustomTypeInfo: customTypeInfo.ToCustomTypeInfo(customTypeInfoId)));
        }
Exemplo n.º 2
0
 void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
     DkmLanguageExpression expression,
     DkmClrModuleInstance moduleInstance,
     int token,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     try
     {
         var runtimeInstance = moduleInstance.RuntimeInstance;
         var appDomain       = moduleInstance.AppDomain;
         var compileResult   = this.CompileWithRetry(
             moduleInstance,
             runtimeInstance.GetMetadataBlocks(appDomain),
             (blocks, useReferencedModulesOnly) => CreateTypeContext(appDomain, blocks, moduleInstance.Mvid, token, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             ResultProperties unusedResultProperties;
             return(context.CompileExpression(
                        RuntimeInspectionContext.Empty,
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        diagnostics,
                        out unusedResultProperties,
                        testData: null));
         },
             out error);
         result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), runtimeInstance);
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error = null;
            result = null;
            using (DebugCompilerContext context = ContextFactory.CreateExpressionContext(inspectionContext, instructionAddress, expression.Text))
            {
                context.GenerateQuery();

                error = context.FirstError;
                if (string.IsNullOrEmpty(error))
                {
                    result = DkmCompiledClrInspectionQuery.Create(
                        instructionAddress.RuntimeInstance,
                        null,
                        expression.Language.Id,
                        new ReadOnlyCollection<byte>(context.GetPeBytes()),
                        context.ClassName,
                        context.MethodName,
                        new ReadOnlyCollection<string>(context.FormatSpecifiers),
                        context.ResultFlags,
                        DkmEvaluationResultCategory.Data,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error  = null;
            result = null;
            using (DebugCompilerContext context = ContextFactory.CreateExpressionContext(inspectionContext, instructionAddress, expression.Text))
            {
                context.GenerateQuery();

                error = context.FirstError;
                if (string.IsNullOrEmpty(error))
                {
                    result = DkmCompiledClrInspectionQuery.Create(
                        instructionAddress.RuntimeInstance,
                        null,
                        expression.Language.Id,
                        new ReadOnlyCollection <byte>(context.GetPeBytes()),
                        context.ClassName,
                        context.MethodName,
                        new ReadOnlyCollection <string>(context.FormatSpecifiers),
                        context.ResultFlags,
                        DkmEvaluationResultCategory.Data,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null);
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// This method is called by the debug engine to compile an expression that the user wants
 /// to evaluate.  Before the call, we have the text of the expression and information about
 /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
 /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
 /// result of the expression.
 /// </summary>
 /// <param name="expression">This is the raw expression to compile</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
 /// to be used during compilation. It also contains the InspectionSession.  The inspection
 /// session is the object that provides lifetime management for our objects.  When the user
 /// steps or continues the process, the debug engine will dispose of the inspection session</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
 void IDkmClrExpressionCompiler.CompileExpression(
     DkmLanguageExpression expression,
     DkmClrInstructionAddress instructionAddress,
     DkmInspectionContext inspectionContext,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     error  = null;
     result = null;
     expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
     return;
 }
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error  = null;
            result = null;
            bool   changed      = false;
            string originalExpr = expression.Text;
            // We use a trick to change the Text when sending it to C#, by retrieveing the field info.
            // This field has a property get but not a property set.
            var fi = typeof(DkmLanguageExpression).GetField("m_Text", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            if (fi != null)
            {
                var newexpr = originalExpr;
                if (expression.Text.StartsWith("SELF", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "this" + originalExpr.Substring(4);
                }
                else if (expression.Text.StartsWith("SUPER", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "base" + originalExpr.Substring(5);
                }
                if (newexpr.Contains(":"))
                {
                    newexpr = newexpr.Replace(':', '.');
                    changed = true;
                }
                // check for literal array
                //var lbrkt = newexpr.IndexOf('[');
                //var rbrkt = newexpr.IndexOf(']');
                //if (lbrkt > 0 && rbrkt > 0 && lbrkt < rbrkt)
                //{
                //    newexpr = AdjustArrayIndices(newexpr, ref changed);
                //}
                if (changed && fi != null)
                {
                    fi.SetValue(expression, newexpr);
                }
            }
            expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
            if (changed && fi != null)
            {
                fi.SetValue(expression, originalExpr);
            }
            return;
        }
Exemplo n.º 7
0
        void IDkmClrExpressionCompiler.CompileAssignment(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmEvaluationResult lValue,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var moduleInstance  = instructionAddress.ModuleInstance;
                var runtimeInstance = instructionAddress.RuntimeInstance;
                var aliases         = GetAliases(runtimeInstance, lValue.InspectionContext); // NB: Not affected by retrying.
                var r = this.CompileWithRetry(
                    moduleInstance.AppDomain,
                    runtimeInstance,
                    (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
                    (context, diagnostics) =>
                {
                    ResultProperties resultProperties;
                    var compileResult = context.CompileAssignment(
                        lValue.FullName,
                        expression.Text,
                        aliases,
                        diagnostics,
                        out resultProperties,
                        testData: null);
                    return(new CompileExpressionResult(compileResult, resultProperties));
                },
                    out error);

                Debug.Assert(
                    r.CompileResult == null && r.ResultProperties.Flags == default ||
                    (r.ResultProperties.Flags & DkmClrCompilationResultFlags.PotentialSideEffect) == DkmClrCompilationResultFlags.PotentialSideEffect);

                result = r.CompileResult.ToQueryResult(this.CompilerId, r.ResultProperties, runtimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Exemplo n.º 8
0
        void IDkmClrExpressionCompiler.CompileAssignment(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmEvaluationResult lValue,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain  = instructionAddress.ModuleInstance.AppDomain;
                var references = instructionAddress.Process.GetMetadataBlocks(appDomain);

                ResultProperties resultProperties;
                ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateMethodContext(instructionAddress, references);
                    compileResult = context.CompileAssignment(
                        RuntimeInspectionContext.Create(lValue.InspectionContext),
                        lValue.FullName,
                        expression.Text,
                        this.DiagnosticFormatter,
                        out resultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                Debug.Assert((resultProperties.Flags & DkmClrCompilationResultFlags.PotentialSideEffect) == DkmClrCompilationResultFlags.PotentialSideEffect);
                result = compileResult.ToQueryResult(this.CompilerId, resultProperties, instructionAddress.RuntimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Exemplo n.º 9
0
        void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
            DkmLanguageExpression expression,
            DkmClrModuleInstance moduleInstance,
            int token,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain  = moduleInstance.AppDomain;
                var references = moduleInstance.Process.GetMetadataBlocks(appDomain);

                ResultProperties unusedResultProperties;
                ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateTypeContext(moduleInstance, references, token);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Empty,
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        this.DiagnosticFormatter,
                        out unusedResultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), moduleInstance.RuntimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Exemplo n.º 10
0
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain = instructionAddress.ModuleInstance.AppDomain;
                var references = instructionAddress.Process.GetMetadataBlocks(appDomain);

                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                ResultProperties resultProperties;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateMethodContext(instructionAddress, references);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Create(inspectionContext),
                        expression.Text,
                        expression.CompilationFlags,
                        this.DiagnosticFormatter,
                        out resultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, resultProperties, instructionAddress.RuntimeInstance);
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Exemplo n.º 11
0
 void IDkmClrExpressionCompiler.CompileExpression(
     DkmLanguageExpression expression,
     DkmClrInstructionAddress instructionAddress,
     DkmInspectionContext inspectionContext,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     try
     {
         var moduleInstance           = instructionAddress.ModuleInstance;
         var runtimeInstance          = instructionAddress.RuntimeInstance;
         var runtimeInspectionContext = RuntimeInspectionContext.Create(inspectionContext);
         var r = this.CompileWithRetry(
             moduleInstance,
             runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
             (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             ResultProperties resultProperties;
             var compileResult = context.CompileExpression(
                 runtimeInspectionContext,
                 expression.Text,
                 expression.CompilationFlags,
                 diagnostics,
                 out resultProperties,
                 testData: null);
             return(new CompileExpressionResult(compileResult, resultProperties));
         },
             out error);
         result = r.CompileResult.ToQueryResult(this.CompilerId, r.ResultProperties, runtimeInstance);
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
 /// <summary>
 /// This method is called by the debug engine when the user modifies the result of a
 /// previous evaluation.  The result of this call will be a query containing the IL code
 /// necessary to assign the value.
 /// </summary>
 /// <param name="expression">The text the user entered as the new value</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="lValue">The L-Value of the assigment.  This is a previous evaluation result.</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query to
 /// execute to perform the assignment.</param>
 void IDkmClrExpressionCompiler.CompileAssignment(DkmLanguageExpression expression, DkmClrInstructionAddress instructionAddress, DkmEvaluationResult lValue, out string error, out DkmCompiledClrInspectionQuery result)
 {
     // when the user assigns a value in the debugger then this method is called.
     // we may want to change an expression like "{1,2,3}" to "new object[] {1,2,3}"
     // and "2020.12.03" to "XSharp.RT.Functions.ConDate(2020,12,03)"
     error  = null;
     result = null;
     expression.CompileAssignment(instructionAddress, lValue, out error, out result);
 }
Exemplo n.º 13
0
        void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
            DkmLanguageExpression expression,
            DkmClrModuleInstance moduleInstance,
            int token,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain = moduleInstance.AppDomain;
                var references = moduleInstance.Process.GetMetadataBlocks(appDomain);

                ResultProperties unusedResultProperties;
                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateTypeContext(moduleInstance, references, token);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Empty,
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        this.DiagnosticFormatter,
                        out unusedResultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), moduleInstance.RuntimeInstance);
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Exemplo n.º 14
0
 /// <summary>
 /// This method is called by the debug engine when the user modifies the result of a
 /// previous evaluation.  The result of this call will be a query containing the IL code
 /// necessary to assign the value.
 /// </summary>
 /// <param name="expression">The text the user entered as the new value</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="lValue">The L-Value of the assigment.  This is a previous evaluation result.</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query to
 /// execute to perform the assignment.</param>
 void IDkmClrExpressionCompiler.CompileAssignment(DkmLanguageExpression expression, DkmClrInstructionAddress instructionAddress, DkmEvaluationResult lValue, out string error, out DkmCompiledClrInspectionQuery result)
 {
     error  = null;
     result = null;
     expression.CompileAssignment(instructionAddress, lValue, out error, out result);
 }