mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8304139: Add <init> and <clinit> method constants to ConstantDescs
Reviewed-by: mchung
This commit is contained in:
parent
d6f20e2fbf
commit
019fcd819c
7 changed files with 56 additions and 21 deletions
|
@ -27,6 +27,7 @@ package java.lang;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.constant.ClassDesc;
|
import java.lang.constant.ClassDesc;
|
||||||
|
import java.lang.constant.ConstantDescs;
|
||||||
import java.lang.invoke.TypeDescriptor;
|
import java.lang.invoke.TypeDescriptor;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.module.ModuleReader;
|
import java.lang.module.ModuleReader;
|
||||||
|
@ -1524,9 +1525,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
return enclosingClass == null || name == null || descriptor == null;
|
return enclosingClass == null || name == null || descriptor == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
|
boolean isConstructor() { return !isPartial() && ConstantDescs.INIT_NAME.equals(name); }
|
||||||
|
|
||||||
boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
|
boolean isMethod() { return !isPartial() && !isConstructor() && !ConstantDescs.CLASS_INIT_NAME.equals(name); }
|
||||||
|
|
||||||
Class<?> getEnclosingClass() { return enclosingClass; }
|
Class<?> getEnclosingClass() { return enclosingClass; }
|
||||||
|
|
||||||
|
@ -2040,8 +2041,8 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
* has length 0. (Note that a {@code Class} object which represents a class
|
* has length 0. (Note that a {@code Class} object which represents a class
|
||||||
* always has public methods, inherited from {@code Object}.)
|
* always has public methods, inherited from {@code Object}.)
|
||||||
*
|
*
|
||||||
* <p> The returned array never contains methods with names "{@code <init>}"
|
* <p> The returned array never contains methods with names {@value
|
||||||
* or "{@code <clinit>}".
|
* ConstantDescs#INIT_NAME} or {@value ConstantDescs#CLASS_INIT_NAME}.
|
||||||
*
|
*
|
||||||
* <p> The elements in the returned array are not sorted and are not in any
|
* <p> The elements in the returned array are not sorted and are not in any
|
||||||
* particular order.
|
* particular order.
|
||||||
|
@ -2234,8 +2235,8 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
* this interface or any of its superinterfaces, then this method does not
|
* this interface or any of its superinterfaces, then this method does not
|
||||||
* find any method.
|
* find any method.
|
||||||
*
|
*
|
||||||
* <p> This method does not find any method with name "{@code <init>}" or
|
* <p> This method does not find any method with name {@value
|
||||||
* "{@code <clinit>}".
|
* ConstantDescs#INIT_NAME} or {@value ConstantDescs#CLASS_INIT_NAME}.
|
||||||
*
|
*
|
||||||
* <p> Generally, the method to be reflected is determined by the 4 step
|
* <p> Generally, the method to be reflected is determined by the 4 step
|
||||||
* algorithm that follows.
|
* algorithm that follows.
|
||||||
|
@ -2293,7 +2294,8 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
* @return the {@code Method} object that matches the specified
|
* @return the {@code Method} object that matches the specified
|
||||||
* {@code name} and {@code parameterTypes}
|
* {@code name} and {@code parameterTypes}
|
||||||
* @throws NoSuchMethodException if a matching method is not found
|
* @throws NoSuchMethodException if a matching method is not found
|
||||||
* or if the name is "<init>"or "<clinit>".
|
* or if the name is {@value ConstantDescs#INIT_NAME} or
|
||||||
|
* {@value ConstantDescs#CLASS_INIT_NAME}.
|
||||||
* @throws NullPointerException if {@code name} is {@code null}
|
* @throws NullPointerException if {@code name} is {@code null}
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* If a security manager, <i>s</i>, is present and
|
* If a security manager, <i>s</i>, is present and
|
||||||
|
@ -2549,8 +2551,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
* object for each such method.
|
* object for each such method.
|
||||||
*
|
*
|
||||||
* <p> If this {@code Class} object represents a class or interface that
|
* <p> If this {@code Class} object represents a class or interface that
|
||||||
* has a class initialization method {@code <clinit>}, then the returned
|
* has a class initialization method {@value ConstantDescs#CLASS_INIT_NAME},
|
||||||
* array does <em>not</em> have a corresponding {@code Method} object.
|
* then the returned array does <em>not</em> have a corresponding {@code
|
||||||
|
* Method} object.
|
||||||
*
|
*
|
||||||
* <p> If this {@code Class} object represents a class or interface with no
|
* <p> If this {@code Class} object represents a class or interface with no
|
||||||
* declared methods, then the returned array has length 0.
|
* declared methods, then the returned array has length 0.
|
||||||
|
@ -2721,7 +2724,8 @@ public final class Class<T> implements java.io.Serializable,
|
||||||
* parameter types is declared in a class, and one of these methods has a
|
* parameter types is declared in a class, and one of these methods has a
|
||||||
* return type that is more specific than any of the others, that method is
|
* return type that is more specific than any of the others, that method is
|
||||||
* returned; otherwise one of the methods is chosen arbitrarily. If the
|
* returned; otherwise one of the methods is chosen arbitrarily. If the
|
||||||
* name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
|
* name is {@value ConstantDescs#INIT_NAME} or {@value
|
||||||
|
* ConstantDescs#CLASS_INIT_NAME} a {@code NoSuchMethodException}
|
||||||
* is raised.
|
* is raised.
|
||||||
*
|
*
|
||||||
* <p> If this {@code Class} object represents an array type, then this
|
* <p> If this {@code Class} object represents an array type, then this
|
||||||
|
|
|
@ -30,6 +30,7 @@ import jdk.internal.misc.VM;
|
||||||
import jdk.internal.module.ModuleHashes;
|
import jdk.internal.module.ModuleHashes;
|
||||||
import jdk.internal.module.ModuleReferenceImpl;
|
import jdk.internal.module.ModuleReferenceImpl;
|
||||||
|
|
||||||
|
import java.lang.constant.ConstantDescs;
|
||||||
import java.lang.module.ModuleReference;
|
import java.lang.module.ModuleReference;
|
||||||
import java.lang.module.ResolvedModule;
|
import java.lang.module.ResolvedModule;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -262,9 +263,9 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||||
* Returns the name of the method containing the execution point
|
* Returns the name of the method containing the execution point
|
||||||
* represented by this stack trace element. If the execution point is
|
* represented by this stack trace element. If the execution point is
|
||||||
* contained in an instance or class initializer, this method will return
|
* contained in an instance or class initializer, this method will return
|
||||||
* the appropriate <i>special method name</i>, {@code <init>} or
|
* the appropriate <i>special method name</i>, {@value ConstantDescs#INIT_NAME}
|
||||||
* {@code <clinit>}, as per Section {@jvms 3.9} of <cite>The Java Virtual
|
* or {@value ConstantDescs#CLASS_INIT_NAME}, as per Section {@jvms 3.9}
|
||||||
* Machine Specification</cite>.
|
* of <cite>The Java Virtual Machine Specification</cite>.
|
||||||
*
|
*
|
||||||
* @return the name of the method containing the execution point
|
* @return the name of the method containing the execution point
|
||||||
* represented by this stack trace element.
|
* represented by this stack trace element.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -299,6 +299,33 @@ public final class ConstantDescs {
|
||||||
= DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
|
= DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
|
||||||
"FALSE", CD_Boolean, CD_Boolean);
|
"FALSE", CD_Boolean, CD_Boolean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The special name of instance initialization methods, {@value}. An instance
|
||||||
|
* initialization method has this special name and is {@code void}.
|
||||||
|
*
|
||||||
|
* @jvms 2.9.1 Instance Initialization Methods
|
||||||
|
* @since 21
|
||||||
|
*/
|
||||||
|
public static final String INIT_NAME = "<init>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The special name of class initialization methods, {@value}. A class
|
||||||
|
* initialization method has this special name, {@link java.lang.reflect.AccessFlag#STATIC
|
||||||
|
* ACC_STATIC} flag set, is {@link #MTD_void void} and takes no arguments.
|
||||||
|
*
|
||||||
|
* @jvms 2.9.2 Class Initialization Methods
|
||||||
|
* @since 21
|
||||||
|
*/
|
||||||
|
public static final String CLASS_INIT_NAME = "<clinit>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nominal descriptor representing the method descriptor {@code ()V},
|
||||||
|
* taking no argument and returning {@code void}.
|
||||||
|
*
|
||||||
|
* @since 21
|
||||||
|
*/
|
||||||
|
public static final MethodTypeDesc MTD_void = MethodTypeDesc.of(CD_void);
|
||||||
|
|
||||||
static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
|
static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
|
||||||
= MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
|
= MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
|
||||||
MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
|
MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
|
||||||
|
|
|
@ -39,7 +39,7 @@ class ConstantUtils {
|
||||||
static final Constable[] EMPTY_CONSTABLE = new Constable[0];
|
static final Constable[] EMPTY_CONSTABLE = new Constable[0];
|
||||||
static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
|
static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
|
||||||
|
|
||||||
private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
|
private static final Set<String> pointyNames = Set.of(ConstantDescs.INIT_NAME, ConstantDescs.CLASS_INIT_NAME);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the correctness of a binary class name. In particular checks for the presence of
|
* Validates the correctness of a binary class name. In particular checks for the presence of
|
||||||
|
|
|
@ -231,7 +231,7 @@ public sealed interface DirectMethodHandleDesc
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the method or field described by this nominal descriptor.
|
* Returns the name of the method or field described by this nominal descriptor.
|
||||||
* For constructors, returns the reserved name {@code "<init>"}.
|
* For constructors, returns the reserved name {@value ConstantDescs#INIT_NAME}.
|
||||||
*
|
*
|
||||||
* @return the name of the method or field
|
* @return the name of the method or field
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -160,7 +160,8 @@ public interface MethodHandleInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the cracked method handle's underlying member.
|
* Returns the name of the cracked method handle's underlying member.
|
||||||
* This is {@code "<init>"} if the underlying member was a constructor,
|
* This is {@value java.lang.constant.ConstantDescs#INIT_NAME}
|
||||||
|
* if the underlying member was a constructor,
|
||||||
* else it is a simple method name or field name.
|
* else it is a simple method name or field name.
|
||||||
* @return the simple name of the underlying member
|
* @return the simple name of the underlying member
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -712,7 +712,8 @@ public class MethodHandles {
|
||||||
* (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
|
* (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
|
||||||
* <p>
|
* <p>
|
||||||
* The JVM represents constructors and static initializer blocks as internal methods
|
* The JVM represents constructors and static initializer blocks as internal methods
|
||||||
* with special names ({@code "<init>"} and {@code "<clinit>"}).
|
* with special names ({@value ConstantDescs#INIT_NAME} and {@value
|
||||||
|
* ConstantDescs#CLASS_INIT_NAME}).
|
||||||
* The internal syntax of invocation instructions allows them to refer to such internal
|
* The internal syntax of invocation instructions allows them to refer to such internal
|
||||||
* methods as if they were normal methods, but the JVM bytecode verifier rejects them.
|
* methods as if they were normal methods, but the JVM bytecode verifier rejects them.
|
||||||
* A lookup of such an internal method will produce a {@code NoSuchMethodException}.
|
* A lookup of such an internal method will produce a {@code NoSuchMethodException}.
|
||||||
|
@ -2768,7 +2769,7 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||||
if (refc.isArray()) {
|
if (refc.isArray()) {
|
||||||
throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
|
throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
|
||||||
}
|
}
|
||||||
String name = "<init>";
|
String name = ConstantDescs.INIT_NAME;
|
||||||
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
|
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
|
||||||
return getDirectConstructor(refc, ctor);
|
return getDirectConstructor(refc, ctor);
|
||||||
}
|
}
|
||||||
|
@ -2964,7 +2965,8 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||||
* {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
|
* {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
|
||||||
* the method's variable arity modifier bit ({@code 0x0080}) is set.
|
* the method's variable arity modifier bit ({@code 0x0080}) is set.
|
||||||
* <p style="font-size:smaller;">
|
* <p style="font-size:smaller;">
|
||||||
* <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API,
|
* <em>(Note: JVM internal methods named {@value ConstantDescs#INIT_NAME}
|
||||||
|
* are not visible to this API,
|
||||||
* even though the {@code invokespecial} instruction can refer to them
|
* even though the {@code invokespecial} instruction can refer to them
|
||||||
* in special circumstances. Use {@link #findConstructor findConstructor}
|
* in special circumstances. Use {@link #findConstructor findConstructor}
|
||||||
* to access instance initialization methods in a safe manner.)</em>
|
* to access instance initialization methods in a safe manner.)</em>
|
||||||
|
@ -4002,7 +4004,7 @@ return mh1;
|
||||||
!refc.isInterface() &&
|
!refc.isInterface() &&
|
||||||
refc != lookupClass().getSuperclass() &&
|
refc != lookupClass().getSuperclass() &&
|
||||||
refc.isAssignableFrom(lookupClass())) {
|
refc.isAssignableFrom(lookupClass())) {
|
||||||
assert(!method.getName().equals("<init>")); // not this code path
|
assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path
|
||||||
|
|
||||||
// Per JVMS 6.5, desc. of invokespecial instruction:
|
// Per JVMS 6.5, desc. of invokespecial instruction:
|
||||||
// If the method is in a superclass of the LC,
|
// If the method is in a superclass of the LC,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue