Mon, 04 May 2009 22:16:46 -0700
Merge
1.1 --- a/src/share/classes/com/sun/tools/classfile/Opcode.java Thu Apr 30 15:04:50 2009 -0700 1.2 +++ b/src/share/classes/com/sun/tools/classfile/Opcode.java Mon May 04 22:16:46 2009 -0700 1.3 @@ -226,7 +226,7 @@ 1.4 INVOKESPECIAL(0xb7, CPREF_W), 1.5 INVOKESTATIC(0xb8, CPREF_W), 1.6 INVOKEINTERFACE(0xb9, CPREF_W_UBYTE_ZERO), 1.7 - // unused 0xba 1.8 + INVOKEDYNAMIC(0xba, CPREF_W_UBYTE_ZERO), 1.9 NEW(0xbb, CPREF_W), 1.10 NEWARRAY(0xbc, ATYPE), 1.11 ANEWARRAY(0xbd, CPREF_W),
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Apr 30 15:04:50 2009 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java Mon May 04 22:16:46 2009 -0700 2.3 @@ -119,6 +119,8 @@ 2.4 public final Type stringBuilderType; 2.5 public final Type cloneableType; 2.6 public final Type serializableType; 2.7 + public final Type methodHandleType; 2.8 + public final Type invokeDynamicType; 2.9 public final Type throwableType; 2.10 public final Type errorType; 2.11 public final Type illegalArgumentExceptionType; 2.12 @@ -289,6 +291,24 @@ 2.13 } 2.14 } 2.15 2.16 + public void synthesizeMHTypeIfMissing(final Type type) { 2.17 + final Completer completer = type.tsym.completer; 2.18 + if (completer != null) { 2.19 + type.tsym.completer = new Completer() { 2.20 + public void complete(Symbol sym) throws CompletionFailure { 2.21 + try { 2.22 + completer.complete(sym); 2.23 + } catch (CompletionFailure e) { 2.24 + sym.flags_field |= (PUBLIC | ABSTRACT); 2.25 + ((ClassType) sym.type).supertype_field = objectType; 2.26 + // do not bother to create MH.type if not visibly declared 2.27 + // this sym just accumulates invoke(...) methods 2.28 + } 2.29 + } 2.30 + }; 2.31 + } 2.32 + } 2.33 + 2.34 public void synthesizeBoxTypeIfMissing(final Type type) { 2.35 ClassSymbol sym = reader.enterClass(boxedName[type.tag]); 2.36 final Completer completer = sym.completer; 2.37 @@ -405,6 +425,8 @@ 2.38 cloneableType = enterClass("java.lang.Cloneable"); 2.39 throwableType = enterClass("java.lang.Throwable"); 2.40 serializableType = enterClass("java.io.Serializable"); 2.41 + methodHandleType = enterClass("java.dyn.MethodHandle"); 2.42 + invokeDynamicType = enterClass("java.dyn.InvokeDynamic"); 2.43 errorType = enterClass("java.lang.Error"); 2.44 illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException"); 2.45 exceptionType = enterClass("java.lang.Exception"); 2.46 @@ -441,6 +463,8 @@ 2.47 2.48 synthesizeEmptyInterfaceIfMissing(cloneableType); 2.49 synthesizeEmptyInterfaceIfMissing(serializableType); 2.50 + synthesizeMHTypeIfMissing(methodHandleType); 2.51 + synthesizeMHTypeIfMissing(invokeDynamicType); 2.52 synthesizeBoxTypeIfMissing(doubleType); 2.53 synthesizeBoxTypeIfMissing(floatType); 2.54
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Apr 30 15:04:50 2009 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon May 04 22:16:46 2009 -0700 3.3 @@ -118,6 +118,7 @@ 3.4 relax = (options.get("-retrofit") != null || 3.5 options.get("-relax") != null); 3.6 useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; 3.7 + allowInvokedynamic = options.get("invokedynamic") != null; 3.8 } 3.9 3.10 /** Switch: relax some constraints for retrofit mode. 3.11 @@ -149,6 +150,10 @@ 3.12 */ 3.13 boolean allowAnonOuterThis; 3.14 3.15 + /** Switch: allow invokedynamic syntax 3.16 + */ 3.17 + boolean allowInvokedynamic; 3.18 + 3.19 /** 3.20 * Switch: warn about use of variable before declaration? 3.21 * RFE: 6425594 3.22 @@ -438,14 +443,22 @@ 3.23 } 3.24 3.25 /** Attribute a type argument list, returning a list of types. 3.26 + * Caller is responsible for calling checkRefTypes. 3.27 */ 3.28 - List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) { 3.29 + List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) { 3.30 ListBuffer<Type> argtypes = new ListBuffer<Type>(); 3.31 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) 3.32 - argtypes.append(chk.checkRefType(l.head.pos(), attribType(l.head, env))); 3.33 + argtypes.append(attribType(l.head, env)); 3.34 return argtypes.toList(); 3.35 } 3.36 3.37 + /** Attribute a type argument list, returning a list of types. 3.38 + * Check that all the types are references. 3.39 + */ 3.40 + List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) { 3.41 + List<Type> types = attribAnyTypes(trees, env); 3.42 + return chk.checkRefTypes(trees, types); 3.43 + } 3.44 3.45 /** 3.46 * Attribute type variables (of generic classes or methods). 3.47 @@ -1194,6 +1207,7 @@ 3.48 3.49 // The types of the actual method type arguments. 3.50 List<Type> typeargtypes = null; 3.51 + boolean typeargtypesNonRefOK = false; 3.52 3.53 Name methName = TreeInfo.name(tree.meth); 3.54 3.55 @@ -1281,7 +1295,7 @@ 3.56 // Otherwise, we are seeing a regular method call. 3.57 // Attribute the arguments, yielding list of argument types, ... 3.58 argtypes = attribArgs(tree.args, localEnv); 3.59 - typeargtypes = attribTypes(tree.typeargs, localEnv); 3.60 + typeargtypes = attribAnyTypes(tree.typeargs, localEnv); 3.61 3.62 // ... and attribute the method using as a prototype a methodtype 3.63 // whose formal argument types is exactly the list of actual 3.64 @@ -1318,6 +1332,20 @@ 3.65 restype.tsym); 3.66 } 3.67 3.68 + // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc) 3.69 + // has type <T>, and T can be a primitive type. 3.70 + if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) { 3.71 + Type selt = ((JCFieldAccess) tree.meth).selected.type; 3.72 + if ((selt == syms.methodHandleType && methName == names.invoke) || selt == syms.invokeDynamicType) { 3.73 + assert types.isSameType(restype, typeargtypes.head) : mtype; 3.74 + typeargtypesNonRefOK = true; 3.75 + } 3.76 + } 3.77 + 3.78 + if (!typeargtypesNonRefOK) { 3.79 + chk.checkRefTypes(tree.typeargs, typeargtypes); 3.80 + } 3.81 + 3.82 // Check that value of resulting type is admissible in the 3.83 // current context. Also, capture the return type 3.84 result = check(tree, capture(restype), VAL, pkind, pt);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Apr 30 15:04:50 2009 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon May 04 22:16:46 2009 -0700 4.3 @@ -207,6 +207,12 @@ 4.4 * @param found The type that was found. 4.5 */ 4.6 Type typeTagError(DiagnosticPosition pos, Object required, Object found) { 4.7 + // this error used to be raised by the parser, 4.8 + // but has been delayed to this point: 4.9 + if (found instanceof Type && ((Type)found).tag == VOID) { 4.10 + log.error(pos, "illegal.start.of.type"); 4.11 + return syms.errType; 4.12 + } 4.13 log.error(pos, "type.found.req", found, required); 4.14 return types.createErrorType(found instanceof Type ? (Type)found : syms.errType); 4.15 } 4.16 @@ -547,6 +553,20 @@ 4.17 } 4.18 } 4.19 4.20 + /** Check that each type is a reference type, i.e. a class, interface or array type 4.21 + * or a type variable. 4.22 + * @param trees Original trees, used for error reporting. 4.23 + * @param types The types to be checked. 4.24 + */ 4.25 + List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) { 4.26 + List<JCExpression> tl = trees; 4.27 + for (List<Type> l = types; l.nonEmpty(); l = l.tail) { 4.28 + l.head = checkRefType(tl.head.pos(), l.head); 4.29 + tl = tl.tail; 4.30 + } 4.31 + return types; 4.32 + } 4.33 + 4.34 /** Check that type is a null or reference type. 4.35 * @param pos Position to be used for error reporting. 4.36 * @param t The type to be checked.
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Apr 30 15:04:50 2009 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon May 04 22:16:46 2009 -0700 5.3 @@ -67,6 +67,7 @@ 5.4 JCDiagnostic.Factory diags; 5.5 public final boolean boxingEnabled; // = source.allowBoxing(); 5.6 public final boolean varargsEnabled; // = source.allowVarargs(); 5.7 + public final boolean allowInvokedynamic; // = options.get("invokedynamic"); 5.8 private final boolean debugResolve; 5.9 5.10 public static Resolve instance(Context context) { 5.11 @@ -104,6 +105,7 @@ 5.12 varargsEnabled = source.allowVarargs(); 5.13 Options options = Options.instance(context); 5.14 debugResolve = options.get("debugresolve") != null; 5.15 + allowInvokedynamic = options.get("invokedynamic") != null; 5.16 } 5.17 5.18 /** error symbols, which are returned when resolution fails 5.19 @@ -881,6 +883,79 @@ 5.20 return bestSoFar; 5.21 } 5.22 5.23 + /** Find or create an implicit method of exactly the given type (after erasure). 5.24 + * Searches in a side table, not the main scope of the site. 5.25 + * This emulates the lookup process required by JSR 292 in JVM. 5.26 + * @param env The current environment. 5.27 + * @param site The original type from where the selection 5.28 + * takes place. 5.29 + * @param name The method's name. 5.30 + * @param argtypes The method's value arguments. 5.31 + * @param typeargtypes The method's type arguments 5.32 + */ 5.33 + Symbol findImplicitMethod(Env<AttrContext> env, 5.34 + Type site, 5.35 + Name name, 5.36 + List<Type> argtypes, 5.37 + List<Type> typeargtypes) { 5.38 + assert allowInvokedynamic; 5.39 + assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke); 5.40 + ClassSymbol c = (ClassSymbol) site.tsym; 5.41 + Scope implicit = c.members().next; 5.42 + if (implicit == null) { 5.43 + c.members().next = implicit = new Scope(c); 5.44 + } 5.45 + Type restype; 5.46 + if (typeargtypes.isEmpty()) { 5.47 + restype = syms.objectType; 5.48 + } else { 5.49 + restype = typeargtypes.head; 5.50 + if (!typeargtypes.tail.isEmpty()) 5.51 + return methodNotFound; 5.52 + } 5.53 + List<Type> paramtypes = Type.map(argtypes, implicitArgType); 5.54 + MethodType mtype = new MethodType(paramtypes, 5.55 + restype, 5.56 + List.<Type>nil(), 5.57 + syms.methodClass); 5.58 + int flags = PUBLIC | ABSTRACT; 5.59 + if (site == syms.invokeDynamicType) flags |= STATIC; 5.60 + Symbol m = null; 5.61 + for (Scope.Entry e = implicit.lookup(name); 5.62 + e.scope != null; 5.63 + e = e.next()) { 5.64 + Symbol sym = e.sym; 5.65 + assert sym.kind == MTH; 5.66 + if (types.isSameType(mtype, sym.type) 5.67 + && (sym.flags() & STATIC) == (flags & STATIC)) { 5.68 + m = sym; 5.69 + break; 5.70 + } 5.71 + } 5.72 + if (m == null) { 5.73 + // create the desired method 5.74 + m = new MethodSymbol(flags, name, mtype, c); 5.75 + implicit.enter(m); 5.76 + } 5.77 + assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(), 5.78 + false, false, Warner.noWarnings); 5.79 + assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings); 5.80 + return m; 5.81 + } 5.82 + //where 5.83 + Mapping implicitArgType = new Mapping ("implicitArgType") { 5.84 + public Type apply(Type t) { return implicitArgType(t); } 5.85 + }; 5.86 + Type implicitArgType(Type argType) { 5.87 + argType = types.erasure(argType); 5.88 + if (argType.tag == BOT) 5.89 + // nulls type as the marker type Null (which has no instances) 5.90 + // TO DO: figure out how to access java.lang.Null safely, else throw nice error 5.91 + //argType = types.boxedClass(syms.botType).type; 5.92 + argType = types.boxedClass(syms.voidType).type; // REMOVE 5.93 + return argType; 5.94 + } 5.95 + 5.96 /** Load toplevel or member class with given fully qualified name and 5.97 * verify that it is accessible. 5.98 * @param env The current environment. 5.99 @@ -1265,6 +1340,14 @@ 5.100 methodResolutionCache.put(steps.head, sym); 5.101 steps = steps.tail; 5.102 } 5.103 + if (sym.kind >= AMBIGUOUS && 5.104 + allowInvokedynamic && 5.105 + (site == syms.invokeDynamicType || 5.106 + site == syms.methodHandleType && name == names.invoke)) { 5.107 + // lookup failed; supply an exactly-typed implicit method 5.108 + sym = findImplicitMethod(env, site, name, argtypes, typeargtypes); 5.109 + env.info.varArgs = false; 5.110 + } 5.111 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 5.112 MethodResolutionPhase errPhase = 5.113 firstErroneousResolutionPhase();
6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java Thu Apr 30 15:04:50 2009 -0700 6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java Mon May 04 22:16:46 2009 -0700 6.3 @@ -225,7 +225,7 @@ 6.4 invokespecial = 183, 6.5 invokestatic = 184, 6.6 invokeinterface = 185, 6.7 - // ___unused___ = 186, 6.8 + invokedynamic = 186, 6.9 new_ = 187, 6.10 newarray = 188, 6.11 anewarray = 189,
7.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Apr 30 15:04:50 2009 -0700 7.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon May 04 22:16:46 2009 -0700 7.3 @@ -2309,6 +2309,7 @@ 7.4 String binaryName = fileManager.inferBinaryName(currentLoc, fo); 7.5 String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); 7.6 if (SourceVersion.isIdentifier(simpleName) || 7.7 + fo.getKind() == JavaFileObject.Kind.CLASS || 7.8 simpleName.equals("package-info")) 7.9 includeClassFile(p, fo); 7.10 break;
8.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu Apr 30 15:04:50 2009 -0700 8.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Mon May 04 22:16:46 2009 -0700 8.3 @@ -456,6 +456,19 @@ 8.4 state.push(mtype.getReturnType()); 8.5 } 8.6 8.7 + /** Emit an invokedynamic instruction. 8.8 + */ 8.9 + public void emitInvokedynamic(int desc, Type mtype) { 8.10 + // N.B. this format is under consideration by the JSR 292 EG 8.11 + int argsize = width(mtype.getParameterTypes()); 8.12 + emitop(invokedynamic); 8.13 + if (!alive) return; 8.14 + emit2(desc); 8.15 + emit2(0); 8.16 + state.pop(argsize); 8.17 + state.push(mtype.getReturnType()); 8.18 + } 8.19 + 8.20 /** Emit an opcode with no operand field. 8.21 */ 8.22 public void emitop0(int op) { 8.23 @@ -2156,7 +2169,7 @@ 8.24 mnem[invokespecial] = "invokespecial"; 8.25 mnem[invokestatic] = "invokestatic"; 8.26 mnem[invokeinterface] = "invokeinterface"; 8.27 - // mnem[___unused___] = "___unused___"; 8.28 + mnem[invokedynamic] = "invokedynamic"; 8.29 mnem[new_] = "new_"; 8.30 mnem[newarray] = "newarray"; 8.31 mnem[anewarray] = "anewarray";
9.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Apr 30 15:04:50 2009 -0700 9.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon May 04 22:16:46 2009 -0700 9.3 @@ -119,6 +119,7 @@ 9.4 : options.get("-g:vars") != null; 9.5 genCrt = options.get("-Xjcov") != null; 9.6 debugCode = options.get("debugcode") != null; 9.7 + allowInvokedynamic = options.get("invokedynamic") != null; 9.8 9.9 generateIproxies = 9.10 target.requiresIproxy() || 9.11 @@ -155,6 +156,7 @@ 9.12 private final boolean varDebugInfo; 9.13 private final boolean genCrt; 9.14 private final boolean debugCode; 9.15 + private final boolean allowInvokedynamic; 9.16 9.17 /** Default limit of (approximate) size of finalizer to inline. 9.18 * Zero means always use jsr. 100 or greater means never use 9.19 @@ -2140,6 +2142,9 @@ 9.20 } 9.21 result = items. 9.22 makeImmediateItem(sym.type, ((VarSymbol) sym).getConstValue()); 9.23 + } else if (allowInvokedynamic && sym.kind == MTH && ssym == syms.invokeDynamicType.tsym) { 9.24 + base.drop(); 9.25 + result = items.makeDynamicItem(sym); 9.26 } else { 9.27 if (!accessSuper) 9.28 sym = binaryQualifier(sym, tree.selected.type);
10.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Items.java Thu Apr 30 15:04:50 2009 -0700 10.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Items.java Mon May 04 22:16:46 2009 -0700 10.3 @@ -139,6 +139,13 @@ 10.4 return new StaticItem(member); 10.5 } 10.6 10.7 + /** Make an item representing a dynamically invoked method. 10.8 + * @param member The represented symbol. 10.9 + */ 10.10 + Item makeDynamicItem(Symbol member) { 10.11 + return new DynamicItem(member); 10.12 + } 10.13 + 10.14 /** Make an item representing an instance variable or method. 10.15 * @param member The represented symbol. 10.16 * @param nonvirtual Is the reference not virtual? (true for constructors 10.17 @@ -457,6 +464,38 @@ 10.18 } 10.19 } 10.20 10.21 + /** An item representing a dynamic call site. 10.22 + */ 10.23 + class DynamicItem extends StaticItem { 10.24 + DynamicItem(Symbol member) { 10.25 + super(member); 10.26 + assert member.owner == syms.invokeDynamicType.tsym; 10.27 + } 10.28 + 10.29 + Item load() { 10.30 + assert false; 10.31 + return null; 10.32 + } 10.33 + 10.34 + void store() { 10.35 + assert false; 10.36 + } 10.37 + 10.38 + Item invoke() { 10.39 + // assert target.hasNativeInvokeDynamic(); 10.40 + MethodType mtype = (MethodType)member.erasure(types); 10.41 + int rescode = Code.typecode(mtype.restype); 10.42 + ClassFile.NameAndType descr = new ClassFile.NameAndType(member.name, mtype); 10.43 + code.emitInvokedynamic(pool.put(descr), mtype); 10.44 + return stackItem[rescode]; 10.45 + } 10.46 + 10.47 + public String toString() { 10.48 + return "dynamic(" + member + ")"; 10.49 + } 10.50 + } 10.51 + 10.52 + 10.53 /** An item representing an instance variable or method. 10.54 */ 10.55 class MemberItem extends Item {
11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Target.java Thu Apr 30 15:04:50 2009 -0700 11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java Mon May 04 22:16:46 2009 -0700 11.3 @@ -253,6 +253,12 @@ 11.4 return compareTo(JDK1_5) >= 0; 11.5 } 11.6 11.7 + /** Does the VM support an invokedynamic instruction? 11.8 + */ 11.9 + public boolean hasInvokedynamic() { 11.10 + return compareTo(JDK1_7) >= 0; 11.11 + } 11.12 + 11.13 /** Although we may not have support for class literals, should we 11.14 * avoid initializing the class that the literal refers to? 11.15 * See 4468823
12.1 --- a/src/share/classes/com/sun/tools/javac/main/Main.java Thu Apr 30 15:04:50 2009 -0700 12.2 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java Mon May 04 22:16:46 2009 -0700 12.3 @@ -268,14 +268,19 @@ 12.4 } 12.5 return null; 12.6 } else { 12.7 - options.put("-target", source.requiredTarget().name); 12.8 + target = source.requiredTarget(); 12.9 + options.put("-target", target.name); 12.10 } 12.11 } else { 12.12 if (targetString == null && !source.allowGenerics()) { 12.13 - options.put("-target", Target.JDK1_4.name); 12.14 + target = Target.JDK1_4; 12.15 + options.put("-target", target.name); 12.16 } 12.17 } 12.18 } 12.19 + if (target.hasInvokedynamic()) { 12.20 + options.put("invokedynamic", "invokedynamic"); 12.21 + } 12.22 return filenames.toList(); 12.23 } 12.24 // where
13.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Apr 30 15:04:50 2009 -0700 13.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon May 04 22:16:46 2009 -0700 13.3 @@ -1034,7 +1034,13 @@ 13.4 return illegal(pos); 13.5 } 13.6 } else { 13.7 - return illegal(); 13.8 + // Support the corner case of myMethodHandle.<void>invoke() by passing 13.9 + // a void type (like other primitive types) to the next phase. 13.10 + // The error will be reported in Attr.attribTypes or Attr.visitApply. 13.11 + JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID)); 13.12 + S.nextToken(); 13.13 + return ti; 13.14 + //return illegal(); 13.15 } 13.16 break; 13.17 default:
14.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java Thu Apr 30 15:04:50 2009 -0700 14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java Mon May 04 22:16:46 2009 -0700 14.3 @@ -317,7 +317,7 @@ 14.4 14.5 /** Read next character in character or string literal and copy into sbuf. 14.6 */ 14.7 - private void scanLitChar() { 14.8 + private void scanLitChar(boolean forBytecodeName) { 14.9 if (ch == '\\') { 14.10 if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { 14.11 bp++; 14.12 @@ -357,6 +357,18 @@ 14.13 putChar('\"'); scanChar(); break; 14.14 case '\\': 14.15 putChar('\\'); scanChar(); break; 14.16 + case '|': case ',': case '?': case '%': 14.17 + case '^': case '_': case '{': case '}': 14.18 + case '!': case '-': case '=': 14.19 + if (forBytecodeName) { 14.20 + // Accept escape sequences for dangerous bytecode chars. 14.21 + // This is illegal in normal Java string or character literals. 14.22 + // Note that the escape sequence itself is passed through. 14.23 + putChar('\\'); putChar(ch); scanChar(); 14.24 + } else { 14.25 + lexError(bp, "illegal.esc.char"); 14.26 + } 14.27 + break; 14.28 default: 14.29 lexError(bp, "illegal.esc.char"); 14.30 } 14.31 @@ -365,6 +377,24 @@ 14.32 putChar(ch); scanChar(); 14.33 } 14.34 } 14.35 + private void scanLitChar() { 14.36 + scanLitChar(false); 14.37 + } 14.38 + 14.39 + /** Read next character in an exotic name #"foo" 14.40 + */ 14.41 + private void scanBytecodeNameChar() { 14.42 + switch (ch) { 14.43 + // reject any "dangerous" char which is illegal somewhere in the JVM spec 14.44 + // cf. http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm 14.45 + case '/': case '.': case ';': // illegal everywhere 14.46 + case '<': case '>': // illegal in methods, dangerous in classes 14.47 + case '[': // illegal in classes 14.48 + lexError(bp, "illegal.bytecode.ident.char", String.valueOf((int)ch)); 14.49 + break; 14.50 + } 14.51 + scanLitChar(true); 14.52 + } 14.53 14.54 /** Read fractional part of hexadecimal floating point number. 14.55 */ 14.56 @@ -915,6 +945,26 @@ 14.57 lexError(pos, "unclosed.str.lit"); 14.58 } 14.59 return; 14.60 + case '#': 14.61 + scanChar(); 14.62 + if (ch == '\"') { 14.63 + scanChar(); 14.64 + if (ch == '\"') 14.65 + lexError(pos, "empty.bytecode.ident"); 14.66 + while (ch != '\"' && ch != CR && ch != LF && bp < buflen) { 14.67 + scanBytecodeNameChar(); 14.68 + } 14.69 + if (ch == '\"') { 14.70 + name = names.fromChars(sbuf, 0, sp); 14.71 + token = IDENTIFIER; // even if #"int" or #"do" 14.72 + scanChar(); 14.73 + } else { 14.74 + lexError(pos, "unclosed.bytecode.ident"); 14.75 + } 14.76 + } else { 14.77 + lexError("illegal.char", String.valueOf((int)'#')); 14.78 + } 14.79 + return; 14.80 default: 14.81 if (isSpecial(ch)) { 14.82 scanOperator();
15.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Apr 30 15:04:50 2009 -0700 15.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon May 04 22:16:46 2009 -0700 15.3 @@ -144,6 +144,8 @@ 15.4 15.5 compiler.err.else.without.if=\ 15.6 ''else'' without ''if'' 15.7 +compiler.err.empty.bytecode.ident=\ 15.8 + empty bytecode identifier 15.9 compiler.err.empty.char.lit=\ 15.10 empty character literal 15.11 compiler.err.encl.class.required=\ 15.12 @@ -186,6 +188,8 @@ 15.13 15.14 compiler.err.icls.cant.have.static.decl=\ 15.15 inner classes cannot have static declarations 15.16 +compiler.err.illegal.bytecode.ident.char=\ 15.17 + illegal bytecode identifier character: \\{0} 15.18 compiler.err.illegal.char=\ 15.19 illegal character: \\{0} 15.20 compiler.err.illegal.char.for.encoding=\ 15.21 @@ -445,6 +449,8 @@ 15.22 compiler.err.types.incompatible.diff.ret=\ 15.23 types {0} and {1} are incompatible; both define {2}, but with unrelated return types 15.24 15.25 +compiler.err.unclosed.bytecode.ident=\ 15.26 + unclosed bytecode identifier 15.27 compiler.err.unclosed.char.lit=\ 15.28 unclosed character literal 15.29 compiler.err.unclosed.comment=\
16.1 --- a/src/share/classes/com/sun/tools/javac/util/Names.java Thu Apr 30 15:04:50 2009 -0700 16.2 +++ b/src/share/classes/com/sun/tools/javac/util/Names.java Mon May 04 22:16:46 2009 -0700 16.3 @@ -73,6 +73,8 @@ 16.4 public final Name java_io_Serializable; 16.5 public final Name serialVersionUID; 16.6 public final Name java_lang_Enum; 16.7 + public final Name java_dyn_MethodHandle; 16.8 + public final Name java_dyn_InvokeDynamic; 16.9 public final Name package_info; 16.10 public final Name ConstantValue; 16.11 public final Name LineNumberTable; 16.12 @@ -111,6 +113,7 @@ 16.13 public final Name value; 16.14 public final Name getMessage; 16.15 public final Name getClass; 16.16 + public final Name invoke; 16.17 public final Name TYPE; 16.18 public final Name FIELD; 16.19 public final Name METHOD; 16.20 @@ -175,6 +178,8 @@ 16.21 java_lang_Cloneable = fromString("java.lang.Cloneable"); 16.22 java_io_Serializable = fromString("java.io.Serializable"); 16.23 java_lang_Enum = fromString("java.lang.Enum"); 16.24 + java_dyn_MethodHandle = fromString("java.dyn.MethodHandle"); 16.25 + java_dyn_InvokeDynamic = fromString("java.dyn.InvokeDynamic"); 16.26 package_info = fromString("package-info"); 16.27 serialVersionUID = fromString("serialVersionUID"); 16.28 ConstantValue = fromString("ConstantValue"); 16.29 @@ -216,6 +221,7 @@ 16.30 value = fromString("value"); 16.31 getMessage = fromString("getMessage"); 16.32 getClass = fromString("getClass"); 16.33 + invoke = fromString("invoke"); 16.34 16.35 TYPE = fromString("TYPE"); 16.36 FIELD = fromString("FIELD");
17.1 --- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java Thu Apr 30 15:04:50 2009 -0700 17.2 +++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java Mon May 04 22:16:46 2009 -0700 17.3 @@ -339,7 +339,7 @@ 17.4 cp = name.codePointAt(k); 17.5 if ((cc == '/' && !Character.isJavaIdentifierStart(cp)) 17.6 || (cp != '/' && !Character.isJavaIdentifierPart(cp))) { 17.7 - return "\"" + name + "\""; 17.8 + return "\"" + addEscapes(name) + "\""; 17.9 } 17.10 cc = cp; 17.11 } 17.12 @@ -347,6 +347,33 @@ 17.13 return name; 17.14 } 17.15 17.16 + /* If name requires escapes, put them in, so it can be a string body. */ 17.17 + private static String addEscapes(String name) { 17.18 + String esc = "\\\"\n\t"; 17.19 + String rep = "\\\"nt"; 17.20 + StringBuilder buf = null; 17.21 + int nextk = 0; 17.22 + int len = name.length(); 17.23 + for (int k = 0; k < len; k++) { 17.24 + char cp = name.charAt(k); 17.25 + int n = esc.indexOf(cp); 17.26 + if (n >= 0) { 17.27 + if (buf == null) 17.28 + buf = new StringBuilder(len * 2); 17.29 + if (nextk < k) 17.30 + buf.append(name, nextk, k); 17.31 + buf.append('\\'); 17.32 + buf.append(rep.charAt(n)); 17.33 + nextk = k+1; 17.34 + } 17.35 + } 17.36 + if (buf == null) 17.37 + return name; 17.38 + if (nextk < len) 17.39 + buf.append(name, nextk, len); 17.40 + return buf.toString(); 17.41 + } 17.42 + 17.43 private ClassWriter classWriter; 17.44 private Options options; 17.45 }
18.1 --- a/src/share/classes/sun/tools/javap/JavapPrinter.java Thu Apr 30 15:04:50 2009 -0700 18.2 +++ b/src/share/classes/sun/tools/javap/JavapPrinter.java Mon May 04 22:16:46 2009 -0700 18.3 @@ -475,6 +475,13 @@ 18.4 return 5; 18.5 } 18.6 18.7 + case opc_invokedynamic: { 18.8 + int index = getUShort(pc+1); 18.9 + out.print("\t#"+index+"; //"); 18.10 + PrintConstant(index); 18.11 + return 5; 18.12 + } 18.13 + 18.14 case opc_multianewarray: { 18.15 int index = getUShort(pc+1), dimensions=getUbyte(pc+3); 18.16 out.print("\t#"+index+", "+dimensions+"; //");
19.1 --- a/src/share/classes/sun/tools/javap/RuntimeConstants.java Thu Apr 30 15:04:50 2009 -0700 19.2 +++ b/src/share/classes/sun/tools/javap/RuntimeConstants.java Mon May 04 22:16:46 2009 -0700 19.3 @@ -318,7 +318,7 @@ 19.4 public static final int opc_invokespecial = 183; 19.5 public static final int opc_invokestatic = 184; 19.6 public static final int opc_invokeinterface = 185; 19.7 -// public static final int opc_xxxunusedxxx = 186; 19.8 + public static final int opc_invokedynamic = 186; 19.9 public static final int opc_new = 187; 19.10 public static final int opc_newarray = 188; 19.11 public static final int opc_anewarray = 189; 19.12 @@ -549,7 +549,7 @@ 19.13 "invokespecial", // was "invokenonvirtual", 19.14 "invokestatic", 19.15 "invokeinterface", 19.16 - "bytecode 186", //"xxxunusedxxx", 19.17 + "invokedynamic", 19.18 "new", 19.19 "newarray", 19.20 "anewarray",
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javac/meth/InvokeDyn.java Mon May 04 22:16:46 2009 -0700 20.3 @@ -0,0 +1,59 @@ 20.4 +/* 20.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 20.24 + * have any questions. 20.25 + */ 20.26 + 20.27 +/* 20.28 + * @test 20.29 + * @bug 6754038 20.30 + * @summary Generate call sites for method handle 20.31 + * @author jrose 20.32 + * 20.33 + * @library .. 20.34 + * @compile -source 7 -target 7 InvokeDyn.java 20.35 + */ 20.36 +//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn 20.37 + 20.38 +/* 20.39 + * Standalone testing: 20.40 + * <code> 20.41 + * $ cd $MY_REPO_DIR/langtools 20.42 + * $ (cd make; make) 20.43 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java 20.44 + * $ javap -c -classpath dist meth.InvokeDyn 20.45 + * </code> 20.46 + */ 20.47 + 20.48 +package meth; 20.49 + 20.50 +import java.dyn.InvokeDynamic; 20.51 + 20.52 +public class InvokeDyn { 20.53 + void test() { 20.54 + Object x = "hello"; 20.55 + InvokeDynamic.greet(x, "world", 123); 20.56 + InvokeDynamic.greet(x, "mundus", 456); 20.57 + InvokeDynamic.greet(x, "kosmos", 789); 20.58 + InvokeDynamic.<String>cogitate(10.11121, 3.14); 20.59 + InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null); 20.60 + InvokeDynamic.<int>invoke("goodbye"); 20.61 + } 20.62 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/tools/javac/meth/InvokeMH.java Mon May 04 22:16:46 2009 -0700 21.3 @@ -0,0 +1,75 @@ 21.4 +/* 21.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 21.24 + * have any questions. 21.25 + */ 21.26 + 21.27 +/* 21.28 + * @test 21.29 + * @bug 6754038 21.30 + * @summary Generate call sites for method handle 21.31 + * @author jrose 21.32 + * 21.33 + * @compile -source 7 -target 7 InvokeMH.java 21.34 + */ 21.35 + 21.36 +/* 21.37 + * Standalone testing: 21.38 + * <code> 21.39 + * $ cd $MY_REPO_DIR/langtools 21.40 + * $ (cd make; make) 21.41 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH.java 21.42 + * $ javap -c -classpath dist meth.InvokeMH 21.43 + * </code> 21.44 + */ 21.45 + 21.46 +package meth; 21.47 + 21.48 +import java.dyn.MethodHandle; 21.49 + 21.50 +public class InvokeMH { 21.51 + void test(MethodHandle mh_SiO, 21.52 + MethodHandle mh_vS, 21.53 + MethodHandle mh_vi, 21.54 + MethodHandle mh_vv) { 21.55 + Object o; String s; int i; // for return type testing 21.56 + 21.57 + // next five must have sig = (String,int)Object 21.58 + mh_SiO.invoke("world", 123); 21.59 + mh_SiO.invoke("mundus", 456); 21.60 + Object k = "kosmos"; 21.61 + mh_SiO.invoke((String)k, 789); 21.62 + o = mh_SiO.invoke((String)null, 000); 21.63 + o = mh_SiO.<Object>invoke("arda", -123); 21.64 + 21.65 + // sig = ()String 21.66 + s = mh_vS.<String>invoke(); 21.67 + 21.68 + // sig = ()int 21.69 + i = mh_vi.<int>invoke(); 21.70 + o = mh_vi.<int>invoke(); 21.71 + //s = mh_vi.<int>invoke(); //BAD 21.72 + mh_vi.<int>invoke(); 21.73 + 21.74 + // sig = ()void 21.75 + //o = mh_vv.<void>invoke(); //BAD 21.76 + mh_vv.<void>invoke(); 21.77 + } 21.78 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javac/meth/MakeNegTests.sh Mon May 04 22:16:46 2009 -0700 22.3 @@ -0,0 +1,98 @@ 22.4 +#!/bin/sh 22.5 + 22.6 +# 22.7 +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 22.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.9 +# 22.10 +# This code is free software; you can redistribute it and/or modify it 22.11 +# under the terms of the GNU General Public License version 2 only, as 22.12 +# published by the Free Software Foundation. 22.13 +# 22.14 +# This code is distributed in the hope that it will be useful, but WITHOUT 22.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.17 +# version 2 for more details (a copy is included in the LICENSE file that 22.18 +# accompanied this code). 22.19 +# 22.20 +# You should have received a copy of the GNU General Public License version 22.21 +# 2 along with this work; if not, write to the Free Software Foundation, 22.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.23 +# 22.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22.25 +# CA 95054 USA or visit www.sun.com if you need additional information or 22.26 +# have any questions. 22.27 +# 22.28 + 22.29 +# @test 22.30 +# @bug 6754038 22.31 +# @summary Verify correct rejection of strongly typed return values 22.32 +# @run shell MakeNegTests.sh 22.33 + 22.34 +default_template=InvokeMH.java 22.35 +javacflags='-source 7 -target 7' 22.36 +# the rest of this file is a generic "//BAD"-line tester 22.37 + 22.38 +: ${TESTSRC=.} ${TESTCLASSES=.} 22.39 +javac="${TESTJAVA+${TESTJAVA}/bin/}javac" 22.40 + 22.41 +verbose=false quiet=false 22.42 + 22.43 +main() { 22.44 + case "${@-}" in 22.45 + *.java*) 22.46 + for template in "$@"; do 22.47 + expand_and_test "$template" 22.48 + done;; 22.49 + *) expand_and_test "${TESTSRC}/$default_template";; 22.50 + esac 22.51 +} 22.52 + 22.53 +expand_and_test() { 22.54 + template=$1 22.55 + expand "$@" 22.56 + testneg "$@" 22.57 +} 22.58 + 22.59 +expand() { 22.60 + template=$1 22.61 + badlines=` grep -n < "$template" '//BAD' ` 22.62 + badcount=` echo "$badlines" | wc -l ` 22.63 + [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; } 22.64 + $quiet || echo "Expanding $badcount negative test cases from $template:" 22.65 + $quiet || echo "$badlines" 22.66 + badnums=` echo "$badlines" | sed 's/:.*//' ` 22.67 + casestem=` getcasestem "$template" ` 22.68 + tclassname=` basename "$template" .java ` 22.69 + rm -f "$casestem"*.java 22.70 + for badnum in $badnums; do 22.71 + casefile="$casestem"${badnum}.java 22.72 + cclassname=` basename "$casefile" .java ` 22.73 + sed < "$template" > "$casefile" " 22.74 + s|@compile|@compile/fail| 22.75 + / @[a-z]/s|@|##| 22.76 + ${badnum}s:^ *[/*]*: : 22.77 + s/${tclassname}/${cclassname}/g 22.78 + " 22.79 + $verbose && diff -u "$template" "$casefile" 22.80 + done 22.81 +} 22.82 + 22.83 +getcasestem() { 22.84 + echo "$1" | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/' 22.85 +} 22.86 + 22.87 +testneg() { 22.88 + template=$1 22.89 + for casefile in ` getcasestem "$template" `*.java; do 22.90 + $quiet || echo -------- $javac $javacflags "$casefile" 22.91 + $javac $javacflags "$casefile" > "$casefile".errlog 2>&1 && { 22.92 + echo "*** Compilation unexpectedly succeeded: $casefile" 22.93 + exit 1 22.94 + } 22.95 + $quiet || echo "Compilation failed as expected" 22.96 + $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog 22.97 + rm "$casefile".errlog 22.98 + done 22.99 +} 22.100 + 22.101 +main "$@"
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/tools/javac/quid/MakeNegTests.sh Mon May 04 22:16:46 2009 -0700 23.3 @@ -0,0 +1,97 @@ 23.4 +#!/bin/sh 23.5 + 23.6 +# 23.7 +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 23.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.9 +# 23.10 +# This code is free software; you can redistribute it and/or modify it 23.11 +# under the terms of the GNU General Public License version 2 only, as 23.12 +# published by the Free Software Foundation. 23.13 +# 23.14 +# This code is distributed in the hope that it will be useful, but WITHOUT 23.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.17 +# version 2 for more details (a copy is included in the LICENSE file that 23.18 +# accompanied this code). 23.19 +# 23.20 +# You should have received a copy of the GNU General Public License version 23.21 +# 2 along with this work; if not, write to the Free Software Foundation, 23.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.23 +# 23.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23.25 +# CA 95054 USA or visit www.sun.com if you need additional information or 23.26 +# have any questions. 23.27 +# 23.28 + 23.29 +# @test 23.30 +# @bug 6746458 23.31 +# @summary Verify correct rejection of illegal quoted identifiers. 23.32 +# @run shell MakeNegTests.sh 23.33 + 23.34 +default_template=QuotedIdent.java 23.35 +# the rest of this file is a generic "//BAD"-line tester 23.36 + 23.37 +: ${TESTSRC=.} ${TESTCLASSES=.} 23.38 +javac="${TESTJAVA+${TESTJAVA}/bin/}javac" 23.39 + 23.40 +verbose=false quiet=false 23.41 + 23.42 +main() { 23.43 + case "${@-}" in 23.44 + *.java*) 23.45 + for template in "$@"; do 23.46 + expand_and_test "$template" 23.47 + done;; 23.48 + *) expand_and_test "${TESTSRC}/$default_template";; 23.49 + esac 23.50 +} 23.51 + 23.52 +expand_and_test() { 23.53 + template=$1 23.54 + expand "$@" 23.55 + testneg "$@" 23.56 +} 23.57 + 23.58 +expand() { 23.59 + template=$1 23.60 + badlines=` grep -n < "$template" '//BAD' ` 23.61 + badcount=` echo "$badlines" | wc -l ` 23.62 + [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; } 23.63 + $quiet || echo "Expanding $badcount negative test cases from $template:" 23.64 + $quiet || echo "$badlines" 23.65 + badnums=` echo "$badlines" | sed 's/:.*//' ` 23.66 + casestem=` getcasestem "$template" ` 23.67 + tclassname=` basename "$template" .java ` 23.68 + rm "$casestem"*.java 23.69 + for badnum in $badnums; do 23.70 + casefile="$casestem"${badnum}.java 23.71 + cclassname=` basename "$casefile" .java ` 23.72 + sed < "$template" > "$casefile" " 23.73 + s|@compile|@compile/fail| 23.74 + / @[a-z]/s|@|##| 23.75 + ${badnum}s:^ *[/*]*: : 23.76 + s/${tclassname}/${cclassname}/g 23.77 + " 23.78 + $verbose && diff -u "$template" "$casefile" 23.79 + done 23.80 +} 23.81 + 23.82 +getcasestem() { 23.83 + echo "$1" | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/' 23.84 +} 23.85 + 23.86 +testneg() { 23.87 + template=$1 23.88 + for casefile in ` getcasestem "$template" `*.java; do 23.89 + $quiet || echo -------- $javac "$casefile" 23.90 + $javac "$casefile" > "$casefile".errlog 2>&1 && { 23.91 + echo "*** Compilation unexpectedly succeeded: $casefile" 23.92 + exit 1 23.93 + } 23.94 + $quiet || echo "Compilation failed as expected" 23.95 + $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog 23.96 + rm "$casefile".errlog 23.97 + done 23.98 +} 23.99 + 23.100 +main "$@"
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/tools/javac/quid/QuotedIdent.java Mon May 04 22:16:46 2009 -0700 24.3 @@ -0,0 +1,132 @@ 24.4 +/* 24.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.7 + * 24.8 + * This code is free software; you can redistribute it and/or modify it 24.9 + * under the terms of the GNU General Public License version 2 only, as 24.10 + * published by the Free Software Foundation. 24.11 + * 24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.15 + * version 2 for more details (a copy is included in the LICENSE file that 24.16 + * accompanied this code). 24.17 + * 24.18 + * You should have received a copy of the GNU General Public License version 24.19 + * 2 along with this work; if not, write to the Free Software Foundation, 24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.21 + * 24.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 24.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 24.24 + * have any questions. 24.25 + */ 24.26 + 24.27 +/* 24.28 + * @test 24.29 + * @bug 6746458 24.30 + * @summary Verify correct lexing of quoted identifiers. 24.31 + * @author jrose 24.32 + * 24.33 + * @library .. 24.34 + * @run main quid.QuotedIdent 24.35 + */ 24.36 + 24.37 +/* 24.38 + * Standalone testing: 24.39 + * <code> 24.40 + * $ cd $MY_REPO_DIR/langtools 24.41 + * $ (cd make; make) 24.42 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent.java 24.43 + * $ java -version # should print 1.6 or later 24.44 + * $ java -cp dist quid.QuotedIdent 24.45 + * </code> 24.46 + */ 24.47 + 24.48 +package quid; 24.49 + 24.50 +public class QuotedIdent { 24.51 + static void check(int testid, String have, String expect) 24.52 + throws RuntimeException { 24.53 + if ((have == null && have != expect) || 24.54 + (have != null && !have.equals(expect))) { 24.55 + String msg = 24.56 + "TEST " + testid + ": HAVE \"" + 24.57 + have + "\" EXPECT \"" + expect + "\""; 24.58 + System.out.println("StringConversion: " + msg); 24.59 + throw new RuntimeException(msg); 24.60 + } 24.61 + } 24.62 + 24.63 + // negative tests: 24.64 + //static class #"" { } //BAD empty ident name 24.65 + //static class #"<foo>" { } //BAD bad char in ident name 24.66 + /*static class /*(//BAD ident name interrupted by newline) #"jump: 24.67 + " { } /* uncomment previous line to attempt class w/ bad name */ 24.68 + 24.69 + static class #"int" extends Number { 24.70 + final int #"int"; 24.71 + #"int"(int #"int") { 24.72 + this.#"int" = #"int"; 24.73 + } 24.74 + static #"int" valueOf(int #"int") { 24.75 + return new #"int"(#"int"); 24.76 + } 24.77 + public int intValue() { return #"int"; } 24.78 + public long longValue() { return #"int"; } 24.79 + public float floatValue() { return #"int"; } 24.80 + public double doubleValue() { return #"int"; } 24.81 + public String toString() { return String.valueOf(#"int"); } 24.82 + } 24.83 + 24.84 + class #"*86" { 24.85 + String #"555-1212"() { return "[*86.555-1212]"; } 24.86 + } 24.87 + static#"*86"#"MAKE-*86"() { // note close spacing 24.88 + return new QuotedIdent().new#"*86"(); 24.89 + } 24.90 + 24.91 + static String bar() { return "[bar]"; } 24.92 + 24.93 + public static void main(String[] args) throws Exception { 24.94 + String s; 24.95 + 24.96 + String #"sticky \' wicket" = "wicked ' stick"; 24.97 + s = #"sticky ' wicket"; 24.98 + check(11, s, "wicked \' stick"); 24.99 + check(12, #"s", s); 24.100 + check(13, #"\163", s); 24.101 + 24.102 + s = #"QuotedIdent".bar(); 24.103 + check(21, s, "[bar]"); 24.104 + 24.105 + s = #"int".valueOf(123).toString(); 24.106 + check(22, s, "123"); 24.107 + 24.108 + s = #"MAKE-*86"().#"555-1212"(); 24.109 + check(23, s, "[*86.555-1212]"); 24.110 + 24.111 + class#"{{{inmost}}}" { } 24.112 + s = new#"{{{inmost}}}"().getClass().getName(); 24.113 + if (!s.endsWith("{{{inmost}}}")) 24.114 + check(24, s, "should end with \"{{{inmost}}}\""); 24.115 + 24.116 + s = #"Yog-Shoggoth".#"(nameless ululation)"; 24.117 + check(25, s, "Tekeli-li!"); 24.118 + 24.119 + s = #"int".class.getName(); 24.120 + check(31, s, QuotedIdent.class.getName()+"$int"); 24.121 + 24.122 + Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86"); 24.123 + if (x86 != #"*86".class) 24.124 + check(32, "reflected "+x86, "static "+#"*86".class); 24.125 + 24.126 + s = (String) x86.getDeclaredMethod("555-1212").invoke(#"MAKE-*86"()); 24.127 + check(31, s, "[*86.555-1212]"); 24.128 + 24.129 + System.out.println("OK"); 24.130 + } 24.131 +} 24.132 + 24.133 +interface #"Yog-Shoggoth" { 24.134 + final String #"(nameless ululation)" = "Tekeli-li!"; 24.135 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/test/tools/javac/quid/QuotedIdent2.java Mon May 04 22:16:46 2009 -0700 25.3 @@ -0,0 +1,81 @@ 25.4 +/* 25.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.7 + * 25.8 + * This code is free software; you can redistribute it and/or modify it 25.9 + * under the terms of the GNU General Public License version 2 only, as 25.10 + * published by the Free Software Foundation. 25.11 + * 25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25.15 + * version 2 for more details (a copy is included in the LICENSE file that 25.16 + * accompanied this code). 25.17 + * 25.18 + * You should have received a copy of the GNU General Public License version 25.19 + * 2 along with this work; if not, write to the Free Software Foundation, 25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 25.21 + * 25.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 25.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 25.24 + * have any questions. 25.25 + */ 25.26 + 25.27 +/* 25.28 + * @test 25.29 + * @bug 6746458 25.30 + * @summary Verify correct separate compilation of classes with extended identifiers. 25.31 + * @author jrose 25.32 + * 25.33 + * @library .. 25.34 + * @run main quid.QuotedIdent2 25.35 + */ 25.36 +/* 25.37 + * Standalone testing: 25.38 + * <code> 25.39 + * $ cd $MY_REPO_DIR/langtools 25.40 + * $ (cd make; make) 25.41 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent.java 25.42 + * $ ./dist/bootstrap/bin/javac -d dist -cp dist test/tools/javac/quid/QuotedIdent2.java 25.43 + * $ java -version # should print 1.6 or later 25.44 + * $ java -cp dist QuotedIdent2 25.45 + * </code> 25.46 + */ 25.47 + 25.48 +package quid; 25.49 + 25.50 +import quid.QuotedIdent.*; 25.51 +import quid.QuotedIdent.#"*86"; 25.52 +import static quid.QuotedIdent.#"MAKE-*86"; 25.53 + 25.54 +public class QuotedIdent2 { 25.55 + static void check(int testid, String have, String expect) 25.56 + throws RuntimeException { 25.57 + QuotedIdent.check(testid, have, expect); 25.58 + } 25.59 + 25.60 + public static void main(String[] args) throws Exception { 25.61 + String s; 25.62 + 25.63 + s = #"int".valueOf(123).toString(); 25.64 + check(22, s, "123"); 25.65 + 25.66 + s = #"MAKE-*86"().#"555-1212"(); 25.67 + check(23, s, "[*86.555-1212]"); 25.68 + 25.69 + s = #"Yog-Shoggoth".#"(nameless ululation)"; 25.70 + check(25, s, "Tekeli-li!"); 25.71 + 25.72 + s = QuotedIdent.#"int".class.getName(); 25.73 + check(31, s, QuotedIdent.class.getName()+"$int"); 25.74 + 25.75 + Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86"); 25.76 + if (x86 != #"*86".class) 25.77 + check(32, "reflected "+x86, "static "+#"*86".class); 25.78 + 25.79 + s = (String) x86.getDeclaredMethod("555-1212").invoke(QuotedIdent.#"MAKE-*86"()); 25.80 + check(31, s, "[*86.555-1212]"); 25.81 + 25.82 + System.out.println("OK"); 25.83 + } 25.84 +}