public void cloneLocals(int whereToStop) {
    oldLVtoSandboxLV = new HashMap<>();
    List<?> oldLocals = getLocals();
    for (int i = 0; i < whereToStop; i++) {
      Type t = lvs.getLocalTypes().get(i);
      if (i == 0 && t == null && (access & ACC_STATIC) == 0)
        t = Type.getType("L" + className + ";");
      if (i < firstLocal && t == null) {
        if ((Opcodes.ACC_STATIC & access) == 0)
          t = Type.getMethodType(this.desc).getArgumentTypes()[i - 1];
        else t = Type.getMethodType(this.desc).getArgumentTypes()[i];
      }
      if (t.getSort() == Type.OBJECT && t.getInternalName().equals("java/lang/Object")) {
        // Default to the type of what we cloened from
        for (Object o : oldLocals) {
          LocalVariableNode lv = (LocalVariableNode) o;
          if (lv.index + 1 == i) {
            t = Type.getType(lv.desc);
            break;
          }
        }
      }

      int idx = lvs.newLocal(t);
      oldLVtoSandboxLV.put(i, idx);
      newLVs.add(new LocalVariableNode("clone_" + i, t.getDescriptor(), null, null, null, idx));

      load(i, t);
      if (t.getSort() == Type.ARRAY || t.getSort() == Type.OBJECT)
        cloneValAtTopOfStack(t.getDescriptor());
      store(idx, t);
    }
  }
  public static boolean methodDescsCloseEnough(String mightHaveVMState, String desc) {
    Type[] d1 = Type.getArgumentTypes(mightHaveVMState);
    Type[] d2 = Type.getArgumentTypes(desc);
    if (Arrays.deepEquals(d1, d2)) return true;
    if (d1[d1.length - 1].getInternalName().equals(Type.getInternalName(VMState.class))) {

      if (d1.length - 1 != d2.length) return false;
      for (int i = 0; i < d1.length - 1; i++) if (!d1[i].equals(d2[i])) return false;
      return true;
    }
    return false;
  }
 public void getSandboxFlag() {
   getSandboxFlagState();
   super.visitMethodInsn(
       INVOKEVIRTUAL, Type.getInternalName(VMState.class), "getState", "()I", false);
 }