Home | History | Annotate | Download | only in art
      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 {
     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 
     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
     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     }
     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     }
     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 
     75   public static native VariableDescription[] GetLocalVariableTable(Executable e);
     76 
     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 
     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 
     97   public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
     98   public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
     99   public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
    100   public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
    101   public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
    102   public static native Object GetLocalInstance(Thread thr, int depth);
    103 
    104   public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
    105     SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
    106   }
    107   public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
    108     SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
    109   }
    110   public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
    111     SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
    112   }
    113   public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
    114     SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
    115   }
    116   public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
    117   public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
    118   public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
    119   public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
    120   public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
    121 }
    122