public LuaValueDataBase LookupTableMember(LuaTableData table, string name) { if (process == null) { return(Report("Can't load table - process memory is not available")); } foreach (var element in table.GetNodeKeys(process)) { var keyAsString = element.LoadKey(process, table.batchNodeElementData) as LuaValueDataString; if (keyAsString == null) { continue; } if (keyAsString.value == name) { return(element.LoadValue(process, table.batchNodeElementData)); } } if (table.HasMetaTable()) { foreach (var element in table.GetMetaTableKeys(process)) { var keyAsString = element.LoadKey(process) as LuaValueDataString; if (keyAsString == null) { continue; } if (keyAsString.value == "__index") { var indexMetaTableValue = element.LoadValue(process); if (indexMetaTableValue is LuaValueDataTable indexMetaTableValueTable) { return(LookupTableMember(indexMetaTableValueTable.value, name)); } } } } return(Report($"Failed to find key '{name}' in table")); }
internal static DkmEvaluationResult GetTableChildAtIndex(DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, string fullName, LuaTableData value, int index) { if (value == null) { return(DkmFailedEvaluationResult.Create(inspectionContext, stackFrame, $"[{index + 1}]", $"{fullName}[{index + 1}]", "Table data is missing", DkmEvaluationResultFlags.Invalid, null)); } var process = stackFrame.Process; var arrayElementCount = value.GetArrayElementCount(process); if (index < arrayElementCount) { var arrayElements = value.GetArrayElements(process); var element = arrayElements[index]; return(EvaluateDataAtLuaValue(inspectionContext, stackFrame, $"[{index + 1}]", $"{fullName}[{index + 1}]", element, DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None)); } index = index - arrayElementCount; var nodeElementCount = value.GetNodeElementCount(process); if (index < nodeElementCount) { var lazyNodeElements = value.GetNodeLazyElements(process); var node = lazyNodeElements[index]; var nodeKey = node.LoadKey(process, value.batchNodeElementData); DkmEvaluationResultFlags flags = DkmEvaluationResultFlags.None; string name = EvaluateValueAtLuaValue(process, nodeKey, 10, out _, ref flags, out _, out _); var keyString = nodeKey as LuaValueDataString; if (keyString != null) { name = keyString.value; } if (name == null || name.Length == 0) { name = "%error-name%"; } // Check if name is an identifier bool isIdentifierName = false; if (char.IsLetter(name[0]) || name[0] == '_') { int pos = 1; while (pos < name.Length && (char.IsLetterOrDigit(name[pos]) || name[pos] == '_')) { pos++; } isIdentifierName = pos == name.Length; } if (isIdentifierName) { return(EvaluateDataAtLuaValue(inspectionContext, stackFrame, name, $"{fullName}.{name}", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None)); } return(EvaluateDataAtLuaValue(inspectionContext, stackFrame, $"\"{name}\"", $"{fullName}[\"{name}\"]", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None)); } index = index - nodeElementCount; if (index == 0 && value.HasMetaTable()) { var metaTableValue = new LuaValueDataTable { baseType = LuaBaseType.Table, extendedType = LuaExtendedType.Table, evaluationFlags = DkmEvaluationResultFlags.ReadOnly, originalAddress = 0, // Not available as TValue value = value.GetMetaTable(process), targetAddress = value.metaTableDataAddress }; return(EvaluateDataAtLuaValue(inspectionContext, stackFrame, "!metatable", $"{fullName}.!metatable", metaTableValue, DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None)); } Debug.Assert(false, "Invalid child index"); return(null); }