1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package art; 18 19 import java.lang.reflect.Executable; 20 import java.util.Objects; 21 22 public class Locals { EnableLocalVariableAccess()23 public static native void EnableLocalVariableAccess(); 24 25 public static class VariableDescription { 26 public final long start_location; 27 public final int length; 28 public final String name; 29 public final String signature; 30 public final String generic_signature; 31 public final int slot; 32 VariableDescription( long start, int length, String name, String sig, String gen_sig, int slot)33 public VariableDescription( 34 long start, int length, String name, String sig, String gen_sig, int slot) { 35 this.start_location = start; 36 this.length = length; 37 this.name = name; 38 this.signature = sig; 39 this.generic_signature = gen_sig; 40 this.slot = slot; 41 } 42 43 @Override toString()44 public String toString() { 45 return String.format( 46 "VariableDescription { " + 47 "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" + 48 "}", 49 this.signature, 50 this.name, 51 this.generic_signature, 52 this.slot, 53 this.start_location, 54 this.length); 55 } equals(Object other)56 public boolean equals(Object other) { 57 if (!(other instanceof VariableDescription)) { 58 return false; 59 } else { 60 VariableDescription v = (VariableDescription)other; 61 return Objects.equals(v.signature, signature) && 62 Objects.equals(v.name, name) && 63 Objects.equals(v.generic_signature, generic_signature) && 64 v.slot == slot && 65 v.start_location == start_location && 66 v.length == length; 67 } 68 } hashCode()69 public int hashCode() { 70 return Objects.hash(this.signature, this.name, this.generic_signature, this.slot, 71 this.start_location, this.length); 72 } 73 } 74 GetLocalVariableTable(Executable e)75 public static native VariableDescription[] GetLocalVariableTable(Executable e); 76 GetVariableAtLine( Executable e, String name, String sig, int line)77 public static VariableDescription GetVariableAtLine( 78 Executable e, String name, String sig, int line) throws Exception { 79 return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line)); 80 } 81 GetVariableAtLocation( Executable e, String name, String sig, long loc)82 public static VariableDescription GetVariableAtLocation( 83 Executable e, String name, String sig, long loc) { 84 VariableDescription[] vars = GetLocalVariableTable(e); 85 for (VariableDescription var : vars) { 86 if (var.start_location <= loc && 87 var.length + var.start_location > loc && 88 var.name.equals(name) && 89 var.signature.equals(sig)) { 90 return var; 91 } 92 } 93 throw new Error( 94 "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc); 95 } 96 GetLocalVariableInt(Thread thr, int depth, int slot)97 public static native int GetLocalVariableInt(Thread thr, int depth, int slot); GetLocalVariableLong(Thread thr, int depth, int slot)98 public static native long GetLocalVariableLong(Thread thr, int depth, int slot); GetLocalVariableFloat(Thread thr, int depth, int slot)99 public static native float GetLocalVariableFloat(Thread thr, int depth, int slot); GetLocalVariableDouble(Thread thr, int depth, int slot)100 public static native double GetLocalVariableDouble(Thread thr, int depth, int slot); GetLocalVariableObject(Thread thr, int depth, int slot)101 public static native Object GetLocalVariableObject(Thread thr, int depth, int slot); GetLocalInstance(Thread thr, int depth)102 public static native Object GetLocalInstance(Thread thr, int depth); 103 SetLocalVariableInt(Thread thr, int depth, int slot, Object val)104 public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) { 105 SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue()); 106 } SetLocalVariableLong(Thread thr, int depth, int slot, Object val)107 public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) { 108 SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue()); 109 } SetLocalVariableFloat(Thread thr, int depth, int slot, Object val)110 public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) { 111 SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue()); 112 } SetLocalVariableDouble(Thread thr, int depth, int slot, Object val)113 public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) { 114 SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue()); 115 } SetLocalVariableInt(Thread thr, int depth, int slot, int val)116 public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val); SetLocalVariableLong(Thread thr, int depth, int slot, long val)117 public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val); SetLocalVariableFloat(Thread thr, int depth, int slot, float val)118 public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val); SetLocalVariableDouble(Thread thr, int depth, int slot, double val)119 public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val); SetLocalVariableObject(Thread thr, int depth, int slot, Object val)120 public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val); 121 } 122