/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Method;

public class Main {
  public static String smallString = generateString(100);
  public static String mediumString = generateString(300);
  public static String largeString = generateString(2000);

  public static String generateString(int length) {
    // Generate a string in the ASCII range that will
    // use string compression.
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
      // Generate repeating alphabet.
      sb.append(Character.valueOf((char)('a' + (i % 26))));
    }
    return sb.toString();
  }

  public static void assertIntEquals(int expected, int result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertBooleanEquals(boolean expected, boolean result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertCharEquals(char expected, char result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertStringEquals(String expected, String result) {
    if (!expected.equals(result)) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertStringContains(String searchTerm, String result) {
    if (result == null || !result.contains(searchTerm)) {
      throw new Error("Search term: " + searchTerm + ", not found in: " + result);
    }
  }

  public static void main(String[] args) {
    stringEqualsSame();
    stringArgumentNotNull("Foo");

    assertIntEquals(0, $opt$noinline$getStringLength(""));
    assertIntEquals(3, $opt$noinline$getStringLength("abc"));
    assertIntEquals(10, $opt$noinline$getStringLength("0123456789"));

    assertBooleanEquals(true, $opt$noinline$isStringEmpty(""));
    assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc"));
    assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789"));

    assertCharEquals('a', $opt$noinline$stringCharAt("a", 0));
    assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0));
    assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1));
    assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2));
    assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7));

    // Single character.
    assertStringEquals("a", stringGetCharsAndBack("a"));
    // Strings < 8 characters.
    assertStringEquals("foobar", stringGetCharsAndBack("foobar"));
    // Strings > 8 characters of various lengths.
    assertStringEquals(smallString, stringGetCharsAndBack(smallString));
    assertStringEquals(mediumString, stringGetCharsAndBack(mediumString));
    assertStringEquals(largeString, stringGetCharsAndBack(largeString));

    // Get only a substring:
    // Substring < 8 characters.
    assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 0));
    // Substring > 8 characters.
    assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 0));

    // Get full string with offset in the char array.
    assertStringEquals(smallString, stringGetCharsAndBackOffset(smallString, 17));

    // Get a substring with an offset in the char array.
    // Substring < 8 characters.
    assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 17));
    // Substring > 8 characters.
    assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 17));

    try {
      $opt$noinline$stringCharAt("abc", -1);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }
    try {
      $opt$noinline$stringCharAt("abc", 3);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }
    try {
      $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }

    assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7));
    assertCharEquals('7', $noinline$runSmaliTest("$noinline$stringCharAtCatch", "0123456789", 7));
    assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10));
    assertCharEquals('\0', $noinline$runSmaliTest("$noinline$stringCharAtCatch","0123456789", 10));

    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc"));
    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3));
    try {
      $opt$noinline$stringSumLeadingChars("abcdef", 7);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringSumLeadingChars",
                           sioob.getStackTrace()[1].toString());
    }
    assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef"));
    try {
      $opt$noinline$stringSum4LeadingChars("abc");
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringSum4LeadingChars",
                           sioob.getStackTrace()[1].toString());
    }
  }

  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (before)
  /// CHECK-DAG:  <<Length:i\d+>>   InvokeVirtual intrinsic:StringLength
  /// CHECK-DAG:                    Return [<<Length>>]

  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:                    Return [<<Length>>]

  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength

  static public int $opt$noinline$getStringLength(String s) {
    return s.length();
  }

  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (before)
  /// CHECK-DAG:  <<IsEmpty:z\d+>>  InvokeVirtual intrinsic:StringIsEmpty
  /// CHECK-DAG:                    Return [<<IsEmpty>>]

  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<IsEmpty:z\d+>>  Equal [<<Length>>,<<Const0>>]
  /// CHECK-DAG:                    Return [<<IsEmpty>>]

  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringIsEmpty

  static public boolean $opt$noinline$isStringEmpty(String s) {
    return s.isEmpty();
  }

  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (before)
  /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt
  /// CHECK-DAG:                    Return [<<Char>>]

  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
  /// CHECK-DAG:                    Return [<<Char>>]

  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  static public char $opt$noinline$stringCharAt(String s, int pos) {
    return s.charAt(pos);
  }

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (before)
  /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
  /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt

  //                                The return value can come from a Phi should the two returns be merged.
  //                                Please refer to the Smali code for a more detailed verification.

  /// CHECK-DAG:                    Return [{{(c|i)\d+}}]

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
  /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
  /// CHECK-DAG:                    Return [{{(c|i)\d+}}]

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  static public char $opt$noinline$stringCharAtCatch(String s, int pos) {
    try {
      return s.charAt(pos);
    } catch (StringIndexOutOfBoundsException ignored) {
      return '\0';
    }
  }

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (before)
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringLength
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-NOT:                    ArrayLength is_string_length:true

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after)
  /// CHECK-NOT:                    BoundsCheck

  static public int $opt$noinline$stringSumChars(String s) {
    int sum = 0;
    int len = s.length();
    for (int i = 0; i < len; ++i) {
      sum += s.charAt(i);
    }
    return sum;
  }

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (before)
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true

  static public int $opt$noinline$stringSumLeadingChars(String s, int n) {
    int sum = 0;
    for (int i = 0; i < n; ++i) {
      sum += s.charAt(i);
    }
    return sum;
  }

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (before)
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true

  static public int $opt$noinline$stringSum4LeadingChars(String s) {
    int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3);
    return sum;
  }

  /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before)
  /// CHECK:      InvokeStaticOrDirect

  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
  /// CHECK:      <<Const1:i\d+>> IntConstant 1
  /// CHECK:      Return [<<Const1>>]

  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static boolean stringEqualsSame() {
    return $inline$callStringEquals("obj", "obj");
  }

  /// CHECK-START: boolean Main.stringEqualsNull() register (after)
  /// CHECK:      <<Invoke:z\d+>> InvokeVirtual
  /// CHECK:      Return [<<Invoke>>]
  public static boolean stringEqualsNull() {
    String o = (String)myObject;
    return $inline$callStringEquals(o, o);
  }

  public static boolean $inline$callStringEquals(String a, String b) {
    return a.equals(b);
  }

  /// CHECK-START-X86: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      test

  /// CHECK-START-X86_64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      test

  /// CHECK-START-ARM: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  // CompareAndBranchIfZero() may emit either CBZ or CMP+BEQ.
  /// CHECK-NOT:      cbz
  /// CHECK-NOT:      cmp {{r\d+}}, #0
  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
  // whichever comes first.
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}

  /// CHECK-START-ARM64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      cbz
  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
  // whichever comes first.
  /// CHECK:          cmp {{w.*,}} {{w.*|#.*}}

  /// CHECK-START-MIPS: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      beq zero,
  /// CHECK-NOT:      beqz
  /// CHECK-NOT:      beqzc
  // Terminate the scope for the CHECK-NOT search at the class field or length comparison,
  // whichever comes first.
  /// CHECK:          lw

  /// CHECK-START-MIPS64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      beqzc
  // Terminate the scope for the CHECK-NOT search at the reference comparison.
  /// CHECK:          beqc
  public static boolean stringArgumentNotNull(Object obj) {
    obj.getClass();
    return "foo".equals(obj);
  }

  // Test is very brittle as it depends on the order we emit instructions.
  /// CHECK-START-X86: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          test
  /// CHECK:          jz/eq
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      mov
  /// CHECK:          cmp

  // Test is very brittle as it depends on the order we emit instructions.
  /// CHECK-START-X86_64: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          test
  /// CHECK:          jz/eq
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      mov
  /// CHECK:          cmp

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-ARM: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          {{cbz|cmp}}
  // Check that we don't try to compare the classes.
  // The dissassembler currently explicitly emits the offset 0 but don't rely on it.
  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
  // equality and one for length comparison but these may be emitted in different order,
  // so repeat the check twice.
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-ARM64: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          cbz
  // Check that we don't try to compare the classes.
  // The dissassembler currently does not explicitly emits the offset 0 but don't rely on it.
  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
  // equality and one for length comparison but these may be emitted in different order,
  // so repeat the check twice.
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-MIPS: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          beq{{(zc)?}}
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
  /// CHECK:          bne{{c?}}

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-MIPS64: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          beqzc
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
  /// CHECK:          bnec
  public static boolean stringArgumentIsString() {
    return "foo".equals(myString);
  }

  static String myString;
  static Object myObject;

  public static char $noinline$runSmaliTest(String name, String str, int pos) {
    try {
      Class<?> c = Class.forName("SmaliTests");
      Method m = c.getMethod(name, String.class, int.class);
      return (Character) m.invoke(null, str, pos);
    } catch (Exception ex) {
      throw new Error(ex);
    }
  }

  public static String stringGetCharsAndBack(String src) {
    char[] dst = new char[src.length()];
    src.getChars(0, src.length(), dst, 0);
    return new String(dst);
  }

  public static String stringGetCharsAndBackOffset(String src, int offset) {
    char[] dst = new char[src.length() + offset];
    src.getChars(0, src.length(), dst, offset);
    return new String(dst, offset, src.length());
  }

  public static String stringGetCharsRange(String src, int srcBegin, int srcEnd, int offset) {
    char[] dst = new char[srcEnd - srcBegin + offset];
    src.getChars(srcBegin, srcEnd, dst, offset);
    return new String(dst, offset, srcEnd - srcBegin);
  }
}
