void do_read_variables(TargetMemoryAccess memory) { if (!is_loaded) throw new TargetException (TargetError.MethodNotLoaded); if (has_variables) return; MonoLanguageBackend mono = file.MonoLanguage; TargetAddress decl_klass = mono.MetadataHelper.MonoMethodGetClass ( memory, address.MonoMethod); TargetType decl = mono.ReadMonoClass (memory, decl_klass); if (decl.HasClassType) decl_type = decl.ClassType; else decl_type = (TargetClassType) decl; do_read_blocks (); locals = new List<TargetVariable> (); parameters = new List<TargetVariable> (); scopes = new Dictionary<int,ScopeInfo> (); var captured_vars = new Dictionary<string,CapturedVariable> (); if (address.HasThis) this_var = new MonoVariable ( "this", decl_type, true, true, this, address.ThisVariableInfo); var scope_list = new List<ScopeInfo> (); C.ScopeVariable[] scope_vars = method.GetScopeVariables (); int num_scope_vars = scope_vars != null ? scope_vars.Length : 0; for (int i = 0; i < num_scope_vars; i++) { C.ScopeVariable sv = scope_vars [i]; VariableInfo var; if (sv.Index < 0) { var = address.ThisVariableInfo; this_is_captured = true; this_var = null; } else var = address.LocalVariableInfo [sv.Index]; try { TargetClassType type = mono.ReadStructType (memory, var.MonoType); MonoVariable scope_var = new MonoVariable ( "$__" + sv.Scope, type, true, type.IsByRef, this, var); ScopeInfo info = new ScopeInfo (sv.Scope, scope_var, type); scopes.Add (sv.Scope, info); scope_list.Add (info); } catch (Exception ex) { Report.Error ("Cannot read scope variable: {0}\n{1}", var, ex); } } foreach (ScopeInfo scope in scope_list) { read_scope (scope); } foreach (ScopeInfo scope in scopes.Values) { C.AnonymousScopeEntry entry = file.File.GetAnonymousScope (scope.ID); foreach (C.CapturedVariable captured in entry.CapturedVariables) { CapturedVariable cv = new CapturedVariable ( scope, this, captured.Name, captured.CapturedName); switch (captured.Kind) { case C.CapturedVariable.CapturedKind.Local: locals.Add (cv); break; case C.CapturedVariable.CapturedKind.Parameter: parameters.Add (cv); break; case C.CapturedVariable.CapturedKind.This: if (!cv.Resolve (memory)) throw new InternalError (); if (cv.Type.HasClassType) decl_type = cv.Type.ClassType; else decl_type = (TargetClassType) cv.Type; this_var = cv; continue; default: throw new InternalError (); } captured_vars.Add (captured.Name, cv); } } var param_info = mdef.Parameters; for (int i = 0; i < param_info.Count; i++) { if (captured_vars.ContainsKey (param_info [i].Name)) continue; VariableInfo var = address.ParamVariableInfo [i]; TargetType type = mono.ReadType (memory, var.MonoType); if (type == null) type = mono.VoidType; parameters.Add (new MonoVariable ( param_info [i].Name, type, false, type.IsByRef, this, var, 0, 0)); } C.LocalVariableEntry[] symfile_locals = method.GetLocals (); for (int i = 0; i < symfile_locals.Length; i++) { C.LocalVariableEntry local = symfile_locals [i]; if (captured_vars.ContainsKey (local.Name)) continue; VariableInfo var = address.LocalVariableInfo [local.Index]; TargetType type = mono.ReadType (memory, var.MonoType); if (type == null) type = mono.VoidType; if (local.BlockIndex > 0) { int index = local.BlockIndex - 1; MonoCodeBlock block = code_blocks [index]; locals.Add (new MonoVariable ( local.Name, type, true, type.IsByRef, this, var, block.StartAddress, block.EndAddress)); } else { locals.Add (new MonoVariable ( local.Name, type, true, type.IsByRef, this, var)); } } has_variables = true; }