/// <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); }