1 // Copyright 2017 The Bazel Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package com.google.devtools.build.android.desugar; 15 16 import static org.objectweb.asm.Opcodes.ASM6; 17 import static org.objectweb.asm.Opcodes.INVOKESTATIC; 18 import static org.objectweb.asm.Opcodes.LCMP; 19 20 import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter; 21 import org.objectweb.asm.ClassVisitor; 22 import org.objectweb.asm.MethodVisitor; 23 24 /** 25 * This class rewrites any call to Long.compare with the JVM instruction lcmp that is semantically 26 * equivalent to Long.compare. 27 */ 28 public class LongCompareMethodRewriter extends ClassVisitor { 29 30 private final CoreLibraryRewriter rewriter; 31 LongCompareMethodRewriter(ClassVisitor cv, CoreLibraryRewriter rewriter)32 public LongCompareMethodRewriter(ClassVisitor cv, CoreLibraryRewriter rewriter) { 33 super(ASM6, cv); 34 this.rewriter = rewriter; 35 } 36 37 @Override visitMethod( int access, String name, String desc, String signature, String[] exceptions)38 public MethodVisitor visitMethod( 39 int access, String name, String desc, String signature, String[] exceptions) { 40 MethodVisitor visitor = super.cv.visitMethod(access, name, desc, signature, exceptions); 41 return visitor == null ? visitor : new LongCompareMethodVisitor(visitor); 42 } 43 44 private class LongCompareMethodVisitor extends MethodVisitor { 45 LongCompareMethodVisitor(MethodVisitor visitor)46 public LongCompareMethodVisitor(MethodVisitor visitor) { 47 super(ASM6, visitor); 48 } 49 50 @Override visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)51 public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 52 if (opcode == INVOKESTATIC 53 && rewriter.unprefix(owner).equals("java/lang/Long") 54 && name.equals("compare") 55 && desc.equals("(JJ)I")) { 56 super.visitInsn(LCMP); 57 } else { 58 super.visitMethodInsn(opcode, owner, name, desc, itf); 59 } 60 } 61 } 62 } 63