001 /* 002 * Copyright 2010-2014 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.jet.codegen.optimization.common; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.org.objectweb.asm.Opcodes; 022 import org.jetbrains.org.objectweb.asm.Type; 023 import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode; 024 import org.jetbrains.org.objectweb.asm.tree.LdcInsnNode; 025 import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException; 026 import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter; 027 import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue; 028 029 public class OptimizationBasicInterpreter extends BasicInterpreter { 030 public static final BasicValue MIXED_VALUE = new BasicValue(Type.getObjectType("#")); 031 private static final BasicValue BOOLEAN_VALUE = new BasicValue(Type.BOOLEAN_TYPE); 032 private static final BasicValue CHAR_VALUE = new BasicValue(Type.CHAR_TYPE); 033 private static final BasicValue BYTE_VALUE = new BasicValue(Type.BYTE_TYPE); 034 private static final BasicValue SHORT_VALUE = new BasicValue(Type.SHORT_TYPE); 035 036 @Override 037 @Nullable 038 public BasicValue newValue(@Nullable Type type) { 039 if (type == null) { 040 return super.newValue(null); 041 } 042 043 switch (type.getSort()) { 044 case Type.VOID: 045 return null; 046 case Type.BOOLEAN: 047 return BOOLEAN_VALUE; 048 case Type.CHAR: 049 return CHAR_VALUE; 050 case Type.BYTE: 051 return BYTE_VALUE; 052 case Type.SHORT: 053 return SHORT_VALUE; 054 case Type.OBJECT: 055 return new BasicValue(type); 056 default: 057 return super.newValue(type); 058 } 059 } 060 061 @Override 062 public BasicValue newOperation(@NotNull AbstractInsnNode insn) throws AnalyzerException { 063 if (insn.getOpcode() == Opcodes.LDC) { 064 Object cst = ((LdcInsnNode) insn).cst; 065 066 if (cst instanceof Long) { 067 return BasicValue.LONG_VALUE; 068 } 069 070 if (cst instanceof Boolean || 071 cst instanceof Integer || 072 cst instanceof Short || 073 cst instanceof Byte || 074 cst instanceof Character) { 075 return BasicValue.INT_VALUE; 076 } 077 078 if (cst instanceof Float) { 079 return BasicValue.FLOAT_VALUE; 080 } 081 082 if (cst instanceof Double) { 083 return BasicValue.DOUBLE_VALUE; 084 } 085 } 086 087 return super.newOperation(insn); 088 } 089 090 @NotNull 091 @Override 092 public BasicValue merge( 093 @NotNull BasicValue v, @NotNull BasicValue w 094 ) { 095 if (!v.equals(w)) { 096 return MIXED_VALUE; 097 } 098 return v; 099 } 100 }