예제 #1
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            completionRoutine(GetChildren(inspectionContext, evaluationResult, dataItem, initialRequestSize));
        }
        string IDkmClrResultProvider.GetUnderlyingString(DkmEvaluationResult result)
        {
            try
            {
                var dataItem = result.GetDataItem<EvalResultDataItem>();
                if (dataItem == null)
                {
                    // We don't know about this result.  Call next implementation
                    return result.GetUnderlyingString();
                }

                return dataItem.Value?.GetUnderlyingString(result.InspectionContext);
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
예제 #3
0
        public unsafe void SetValueAsString(DkmEvaluationResult result, string value, int timeout, out string errorText) {
            var pyEvalResult = result.GetDataItem<PyObjectEvaluationResult>();
            if (pyEvalResult == null) {
                Debug.Fail("SetValueAsString called on a DkmEvaluationResult without an associated PyObjectEvaluationResult.");
                throw new NotSupportedException();
            }

            var proxy = pyEvalResult.ValueStore as IWritableDataProxy;
            if (proxy == null) {
                Debug.Fail("SetValueAsString called on a DkmEvaluationResult that does not correspond to an IWritableDataProxy.");
                throw new InvalidOperationException();
            }

            errorText = null;
            var process = result.StackFrame.Process;
            var pyrtInfo = process.GetPythonRuntimeInfo();

            var parserOptions = new ParserOptions { ErrorSink = new StringErrorSink() };
            var parser = Parser.CreateParser(new StringReader(value), pyrtInfo.LanguageVersion, parserOptions);
            var body = (ReturnStatement)parser.ParseTopExpression().Body;
            errorText = parserOptions.ErrorSink.ToString();
            if (!string.IsNullOrEmpty(errorText)) {
                return;
            }

            var expr = body.Expression;
            while (true) {
                var parenExpr = expr as ParenthesisExpression;
                if (parenExpr == null) {
                    break;
                }
                expr = parenExpr.Expression;
            }

            int sign;
            expr = ForceExplicitSign(expr, out sign);

            PyObject newObj = null;

            var constExpr = expr as ConstantExpression;
            if (constExpr != null) {
                if (constExpr.Value == null) {
                    newObj = PyObject.None(process);
                } else if (constExpr.Value is bool) {
                    // In 2.7, 'True' and 'False' are reported as identifiers, not literals, and are handled separately below.
                    newObj = PyBoolObject33.Create(process, (bool)constExpr.Value);
                } else if (constExpr.Value is string) {
                    if (pyrtInfo.LanguageVersion <= PythonLanguageVersion.V27) {
                        newObj = PyUnicodeObject27.Create(process, (string)constExpr.Value);
                    } else {
                        newObj = PyUnicodeObject33.Create(process, (string)constExpr.Value);
                    }
                } else if (constExpr.Value is AsciiString) {
                    newObj = PyBytesObject.Create(process, (AsciiString)constExpr.Value);
                }
            } else {
                var unaryExpr = expr as UnaryExpression;
                if (unaryExpr != null && sign != 0) {
                    constExpr = unaryExpr.Expression as ConstantExpression;
                    if (constExpr != null) {
                        if (constExpr.Value is BigInteger) {
                            newObj = PyLongObject.Create(process, (BigInteger)constExpr.Value * sign);
                        } else if (constExpr.Value is int) {
                            if (pyrtInfo.LanguageVersion <= PythonLanguageVersion.V27) {
                                newObj = PyIntObject.Create(process, (int)constExpr.Value * sign);
                            } else {
                                newObj = PyLongObject.Create(process, (int)constExpr.Value * sign);
                            }
                        } else if (constExpr.Value is double) {
                            newObj = PyFloatObject.Create(process, (double)constExpr.Value * sign);
                        } else if (constExpr.Value is Complex) {
                            newObj = PyComplexObject.Create(process, (Complex)constExpr.Value * sign);
                        }
                    }
                } else {
                    var binExpr = expr as BinaryExpression;
                    if (binExpr != null && (binExpr.Operator == PythonOperator.Add || binExpr.Operator == PythonOperator.Subtract)) {
                        int realSign;
                        var realExpr = ForceExplicitSign(binExpr.Left, out realSign) as UnaryExpression;
                        int imagSign;
                        var imagExpr = ForceExplicitSign(binExpr.Right, out imagSign) as UnaryExpression;
                        if (realExpr != null && realSign != 0 && imagExpr != null && imagSign != 0) {
                            var realConst = realExpr.Expression as ConstantExpression;
                            var imagConst = imagExpr.Expression as ConstantExpression;
                            if (realConst != null && imagConst != null) {
                                var realVal = (realConst.Value as int? ?? realConst.Value as double?) as IConvertible;
                                var imagVal = imagConst.Value as Complex?;
                                if (realVal != null && imagVal != null) {
                                    double real = realVal.ToDouble(null) * realSign;
                                    double imag = imagVal.Value.Imaginary * imagSign * (binExpr.Operator == PythonOperator.Add ? 1 : -1);
                                    newObj = PyComplexObject.Create(process, new Complex(real, imag));
                                }
                            }
                        }
                    } else {
                        if (pyrtInfo.LanguageVersion <= PythonLanguageVersion.V27) {
                            // 'True' and 'False' are not literals in 2.x, but we want to treat them as such.
                            var name = expr as NameExpression;
                            if (name != null) {
                                if (name.Name == "True") {
                                    newObj = PyBoolObject27.Create(process, true);
                                } else if (name.Name == "False") {
                                    newObj = PyBoolObject27.Create(process, false);
                                }
                            }
                        }
                    }
                }
            }

            if (newObj != null) {
                var oldObj = proxy.Read() as PyObject;
                if (oldObj != null) {
                    // We can't free the original value without running some code in the process, and it may be holding heap locks.
                    // So don't decrement refcount now, but instead add it to the list of objects for TraceFunc to GC when it gets
                    // a chance to run next time.
                    _process.GetDataItem<PyObjectAllocator>().QueueForDecRef(oldObj);
                }

                newObj.ob_refcnt.Increment();
                proxy.Write(newObj);
            } else {
                errorText = "Only boolean, numeric or string literals and None are supported.";
            }
        }
예제 #4
0
        public string GetUnderlyingString(DkmEvaluationResult result) {
            var rawResult = result.GetDataItem<RawEvaluationResult>();
            if (rawResult != null && rawResult.Value is string) {
                return (string)rawResult.Value;
            }

            var objResult = result.GetDataItem<PyObjectEvaluationResult>();
            if (objResult == null) {
                return null;
            }

            var str = objResult.ValueStore.Read() as IPyBaseStringObject;
            return str.ToStringOrNull();
        }
예제 #5
0
        public void GetChildren(DkmEvaluationResult result, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) {
            var asyncEvalResult = result.GetDataItem<CppViewEvaluationResult>();
            if (asyncEvalResult != null) {
                asyncEvalResult.GetChildren(result, workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var pyEvalResult =
                (IPythonEvaluationResult)result.GetDataItem<PyObjectEvaluationResult>() ??
                (IPythonEvaluationResult)result.GetDataItem<GlobalsEvaluationResult>();
            if (pyEvalResult != null) {
                var childResults = pyEvalResult.GetChildren(this, result, inspectionContext);
                completionRoutine(
                    new DkmGetChildrenAsyncResult(
                        new DkmEvaluationResult[0],
                        DkmEvaluationResultEnumContext.Create(
                            childResults.Count,
                            result.StackFrame,
                            inspectionContext,
                            new EvaluationResults { Results = childResults.ToArray() })));
                return;
            }

            Debug.Fail("GetChildren called on an unsupported DkmEvaluationResult.");
            throw new NotSupportedException();
        }
예제 #6
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var expansion = dataItem.Expansion;
            if (expansion == null)
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(0, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], enumContext));
                return;
            }

            // Evaluate children with InspectionContext that is not the root.
            inspectionContext = inspectionContext.With(NotRoot);

            var rows = ArrayBuilder<EvalResult>.GetInstance();
            int index = 0;
            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
            var numRows = rows.Count;
            Debug.Assert(index >= numRows);
            Debug.Assert(initialRequestSize >= numRows);
            var initialChildren = new DkmEvaluationResult[numRows];
            CompletionRoutine<Exception> onException = e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);
            wl.ContinueWith(() =>
                GetEvaluationResultsAndContinue(evaluationResult, rows, initialChildren, 0, numRows, wl, inspectionContext,
                    () =>
                    wl.ContinueWith(
                        () =>
                        {
                            var enumContext = DkmEvaluationResultEnumContext.Create(index, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                            completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                            rows.Free();
                        }),
                    onException));
        }