internal EvaluationContext( ITraceWriter trace, ISecretMasker secretMasker, Object state, EvaluationOptions options, ExpressionNode node) { ArgumentUtility.CheckForNull(trace, nameof(trace)); ArgumentUtility.CheckForNull(secretMasker, nameof(secretMasker)); Trace = trace; SecretMasker = secretMasker; State = state; // Copy the options options = new EvaluationOptions(copy: options); if (options.MaxMemory == 0) { // Set a reasonable default max memory options.MaxMemory = 1048576; // 1 mb } Options = options; Memory = new EvaluationMemory(options.MaxMemory, node); m_traceResults = new Dictionary <ExpressionNode, String>(); m_traceMemory = new MemoryCounter(null, options.MaxMemory); }
/// <summary> /// This function is intended only for ExpressionNode authors to call. The EvaluationContext /// caches result-state specific to the evaluation instance. /// </summary> public EvaluationResult Evaluate(EvaluationContext context) { // Evaluate Level = Container == null ? 0 : Container.Level + 1; TraceVerbose(context, Level, $"Evaluating {Name}:"); var coreResult = EvaluateCore(context, out ResultMemory coreMemory); if (coreMemory == null) { coreMemory = new ResultMemory(); } // Convert to canonical value var val = ExpressionUtility.ConvertToCanonicalValue(coreResult, out ValueKind kind, out Object raw); // The depth can be safely trimmed when the total size of the core result is known, // or when the total size of the core result can easily be determined. var trimDepth = coreMemory.IsTotal || (Object.ReferenceEquals(raw, null) && ExpressionUtility.IsPrimitive(kind)); // Account for the memory overhead of the core result var coreBytes = coreMemory.Bytes ?? EvaluationMemory.CalculateBytes(raw ?? val); context.Memory.AddAmount(Level, coreBytes, trimDepth); // Account for the memory overhead of the conversion result if (!Object.ReferenceEquals(raw, null)) { var conversionBytes = EvaluationMemory.CalculateBytes(val); context.Memory.AddAmount(Level, conversionBytes); } var result = new EvaluationResult(context, Level, val, kind, raw); // Store the trace result if (this.TraceFullyRealized) { context.SetTraceResult(this, result); } return(result); }