Mono.Debugger.Backend.Mono.MonoSymbolFile.MonoMethod.do_read_variables C# (CSharp) Method

do_read_variables() private method

private do_read_variables ( TargetMemoryAccess memory ) : void
memory Mono.Debugger.TargetMemoryAccess
return void
            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);
                    }
                }

                Cecil.ParameterDefinitionCollection 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;
            }