public static ConstFold instance(Context context) { ConstFold instance = context.get(constFoldKey); if (instance == null) instance = new ConstFold(context); return instance; }
return operand; case ineg: // unary - return syms.intType.constType(-intValue(od)); case ixor: // ~ return syms.intType.constType(~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)); return syms.longType.constType(new Long(-longValue(od))); case lxor: // ~ return syms.longType.constType(new Long(~longValue(od))); return syms.floatType.constType(new Float(-floatValue(od))); return syms.doubleType.constType(new Double(-doubleValue(od)));
public Type coerce(Type etype, Type ttype) { return cfolder.coerce(etype, ttype); }
/** 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<Type> argtypes) { int argCount = argtypes.length(); if (argCount == 1) return fold1(opcode, argtypes.head); else if (argCount == 2) return fold2(opcode, argtypes.head, argtypes.tail.head); else throw new AssertionError(); }
Type t1 = fold2(opcode >> ByteCodes.preShift, left, right); return (t1.constValue() == null) ? t1 : fold1(opcode & ByteCodes.preMask, t1); } else { Object l = left.constValue(); switch (opcode) { case iadd: return syms.intType.constType(intValue(l) + intValue(r)); case isub: return syms.intType.constType(intValue(l) - intValue(r)); case imul: return syms.intType.constType(intValue(l) * intValue(r)); case idiv: return syms.intType.constType(intValue(l) / intValue(r)); case imod: return syms.intType.constType(intValue(l) % intValue(r)); case iand: return (left.tag == BOOLEAN ? syms.booleanType : syms.intType) .constType(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(intValue(l) | intValue(r)); case bool_or: return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
protected Annotate(Context context) { context.put(annotateKey, this); attr = Attr.instance(context); make = TreeMaker.instance(context); log = Log.instance(context); syms = Symtab.instance(context); names = Names.instance(context); rs = Resolve.instance(context); types = Types.instance(context); cfolder = ConstFold.instance(context); chk = Check.instance(context); }
tree.type = cfolder.fold1(bool_not, tree.arg.type);
Type t1 = fold2(opcode >> ByteCodes.preShift, left, right); return (t1.constValue() == null) ? t1 : fold1(opcode & ByteCodes.preMask, t1); } else { Object l = left.constValue(); switch (opcode) { case iadd: return syms.intType.constType(intValue(l) + intValue(r)); case isub: return syms.intType.constType(intValue(l) - intValue(r)); case imul: return syms.intType.constType(intValue(l) * intValue(r)); case idiv: return syms.intType.constType(intValue(l) / intValue(r)); case imod: return syms.intType.constType(intValue(l) % intValue(r)); case iand: return (left.tag == BOOLEAN ? syms.booleanType : syms.intType) .constType(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(intValue(l) | intValue(r)); case bool_or: return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
/** 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<Type> argtypes) { int argCount = argtypes.length(); if (argCount == 1) return fold1(opcode, argtypes.head); else if (argCount == 2) return fold2(opcode, argtypes.head, argtypes.tail.head); else throw new AssertionError(); }
protected Annotate(Context context) { context.put(annotateKey, this); attr = Attr.instance(context); make = TreeMaker.instance(context); log = Log.instance(context); syms = Symtab.instance(context); names = Name.Table.instance(context); rs = Resolve.instance(context); types = Types.instance(context); cfolder = ConstFold.instance(context); chk = Check.instance(context); }
tree.type = cfolder.fold1(bool_not, tree.arg.type);
return operand; case ineg: // unary - return syms.intType.constType(-intValue(od)); case ixor: // ~ return syms.intType.constType(~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)); return syms.longType.constType(new Long(-longValue(od))); case lxor: // ~ return syms.longType.constType(new Long(~longValue(od))); return syms.floatType.constType(new Float(-floatValue(od))); return syms.doubleType.constType(new Double(-doubleValue(od)));
Type t1 = fold2(opcode >> ByteCodes.preShift, left, right); return (t1.constValue() == null) ? t1 : fold1(opcode & ByteCodes.preMask, t1); } else { Object l = left.constValue(); switch (opcode) { case iadd: return syms.intType.constType(intValue(l) + intValue(r)); case isub: return syms.intType.constType(intValue(l) - intValue(r)); case imul: return syms.intType.constType(intValue(l) * intValue(r)); case idiv: return syms.intType.constType(intValue(l) / intValue(r)); case imod: return syms.intType.constType(intValue(l) % intValue(r)); case iand: return (left.hasTag(BOOLEAN) ? syms.booleanType : syms.intType) .constType(intValue(l) & intValue(r)); case bool_and: return syms.booleanType.constType(b2i((intValue(l) & intValue(r)) != 0)); case ior: return (left.hasTag(BOOLEAN) ? syms.booleanType : syms.intType) .constType(intValue(l) | intValue(r)); case bool_or: return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
public Type coerce(Type etype, Type ttype) { return cfolder.coerce(etype, ttype); }
/** 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<Type> argtypes) { int argCount = argtypes.length(); if (argCount == 1) return fold1(opcode, argtypes.head); else if (argCount == 2) return fold2(opcode, argtypes.head, argtypes.tail.head); else throw new AssertionError(); }
public void visitUnary(JCUnary tree) { // Attribute arguments. Type argtype = (tree.getTag().isIncOrDecUnaryOp()) ? attribTree(tree.arg, env, varInfo) : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); // Find operator. Symbol operator = tree.operator = rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype); Type owntype = types.createErrorType(tree.type); if (operator.kind == MTH && !argtype.isErroneous()) { owntype = (tree.getTag().isIncOrDecUnaryOp()) ? tree.arg.type : operator.type.getReturnType(); int opc = ((OperatorSymbol)operator).opcode; // If the argument is constant, fold it. if (argtype.constValue() != null) { Type ctype = cfolder.fold1(opc, argtype); if (ctype != null) { owntype = cfolder.coerce(ctype, owntype); } } } result = check(tree, owntype, VAL, resultInfo); }