📄 constfold.java
字号:
/** * @(#)ConstFold.java 1.17 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.comp;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.*;import com.sun.tools.javac.v8.code.Type.*;/** * Helper class for constant folding, used by the attribution phase */strictfp class ConstFold implements TypeTags, ByteCodes { private static final Context.Key constFoldKey = new Context.Key(); private Log log; private Symtab syms; public static ConstFold instance(Context context) { ConstFold instance = (ConstFold) context.get(constFoldKey); if (instance == null) instance = new ConstFold(context); return instance; } private ConstFold(Context context) { super(); context.put(constFoldKey, this); log = Log.instance(context); syms = Symtab.instance(context); } static Integer minusOne = new Integer(-1); static Integer zero = new Integer(0); static Integer one = new Integer(1); /** * Convert boolean to integer (true = 1, false = 0). */ private static Integer b2i(boolean b) { return b ? one : zero; } private static int intValue(Object x) { return ((Number) x).intValue(); } private static long longValue(Object x) { return ((Number) x).longValue(); } private static float floatValue(Object x) { return ((Number) x).floatValue(); } private static double doubleValue(Object x) { return ((Number) x).doubleValue(); } /** * Fold binary or unary operation, returning constant type reflecting the * operations result. Return null if fold failed due to an * arithmetic exception. * @param opcode The operation's opcode instruction (usually a byte code), * as entered by class Symtab. * @param argtypes The operation's argument types (a list of length 1 or 2). * Argument types are assumed to have non-null constValue's. */ Type fold(int opcode, List argtypes) { int argCount = argtypes.length(); if (argCount == 1) return fold1(opcode, (Type) argtypes.head); else if (argCount == 2) return fold2(opcode, (Type) argtypes.head, (Type) argtypes.tail.head); else throw new AssertionError(); } /** * Fold unary operation. * @param opcode The operation's opcode instruction (usually a byte code), * as entered by class Symtab. * opcode's ifeq to ifge are for postprocessing * xcmp; ifxx pairs of instructions. * @param operand The operation's operand type. * Argument types are assumed to have non-null constValue's. */ Type fold1(int opcode, Type operand) { try { Object od = operand.constValue; switch (opcode) { case nop: return operand; case ineg: return syms.intType.constType(new Integer(-intValue(od))); case ixor: return syms.intType.constType(new Integer(~intValue(od))); case bool_not: return syms.booleanType.constType(b2i(intValue(od) == 0)); case ifeq: return syms.booleanType.constType(b2i(intValue(od) == 0)); case ifne: return syms.booleanType.constType(b2i(intValue(od) != 0)); case iflt: return syms.booleanType.constType(b2i(intValue(od) < 0)); case ifgt: return syms.booleanType.constType(b2i(intValue(od) > 0)); case ifle: return syms.booleanType.constType(b2i(intValue(od) <= 0)); case ifge: return syms.booleanType.constType(b2i(intValue(od) >= 0)); case lneg: return syms.longType.constType(new Long(-longValue(od))); case lxor: return syms.longType.constType(new Long(~longValue(od))); case fneg: return syms.floatType.constType(new Float(-floatValue(od))); case dneg: return syms.doubleType.constType(new Double(-doubleValue(od))); default: return null; } } catch (ArithmeticException e) { return null; } } /** * Fold binary operation. * @param opcode The operation's opcode instruction (usually a byte code), * as entered by class Symtab. * opcode's ifeq to ifge are for postprocessing * xcmp; ifxx pairs of instructions. * @param left The type of the operation's left operand. * @param right The type of the operation's right operand. */ Type fold2(int opcode, Type left, Type right) { try { if (opcode > ByteCodes.preMask) { Type t1 = fold2(opcode >> ByteCodes.preShift, left, right); return (t1.constValue == null) ? t1 : fold1(opcode & ByteCodes.preMask, t1); } else { Object l = left.constValue; Object r = right.constValue; switch (opcode) { case iadd: return syms.intType.constType( new Integer(intValue(l) + intValue(r))); case isub: return syms.intType.constType( new Integer(intValue(l) - intValue(r))); case imul: return syms.intType.constType( new Integer(intValue(l) * intValue(r))); case idiv: return syms.intType.constType( new Integer(intValue(l) / intValue(r))); case imod: return syms.intType.constType( new Integer(intValue(l) % intValue(r))); case iand: return (left.tag == BOOLEAN ? syms.booleanType : syms.intType).constType( new Integer(intValue(l) & intValue(r))); case bool_and: return syms.booleanType.constType( b2i((intValue(l) & intValue(r)) != 0)); case ior: return (left.tag == BOOLEAN ? syms.booleanType : syms.intType).constType( new Integer(intValue(l) | intValue(r))); case bool_or: return syms.booleanType.constType( b2i((intValue(l) | intValue(r)) != 0)); case ixor: return (left.tag == BOOLEAN ? syms.booleanType : syms.intType).constType( new Integer(intValue(l) ^ intValue(r))); case ishl: case ishll: return syms.intType.constType( new Integer(intValue(l)<< intValue(r))); case ishr: case ishrl: return syms.intType.constType( new Integer(intValue(l)>> intValue(r))); case iushr:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -