@@ -1906,9 +1906,12 @@ public enum ClassOption {
19061906 this .flag = flag ;
19071907 }
19081908
1909- static int optionsToFlag (Set < ClassOption > options ) {
1909+ static int optionsToFlag (ClassOption [] options ) {
19101910 int flags = 0 ;
19111911 for (ClassOption cp : options ) {
1912+ if ((flags & cp .flag ) != 0 ) {
1913+ throw new IllegalArgumentException ("Duplicate ClassOption " + cp );
1914+ }
19121915 flags |= cp .flag ;
19131916 }
19141917 return flags ;
@@ -2126,14 +2129,13 @@ public Lookup defineHiddenClass(byte[] bytes, boolean initialize, ClassOption...
21262129 throws IllegalAccessException
21272130 {
21282131 Objects .requireNonNull (bytes );
2129- Objects .requireNonNull (options );
2130-
2132+ int flags = ClassOption .optionsToFlag (options );
21312133 ensureDefineClassPermission ();
21322134 if (!hasFullPrivilegeAccess ()) {
21332135 throw new IllegalAccessException (this + " does not have full privilege access" );
21342136 }
21352137
2136- return makeHiddenClassDefiner (bytes .clone (), Set . of ( options ), false ).defineClassAsLookup (initialize );
2138+ return makeHiddenClassDefiner (bytes .clone (), false , flags ).defineClassAsLookup (initialize );
21372139 }
21382140
21392141 /**
@@ -2213,14 +2215,15 @@ public Lookup defineHiddenClassWithClassData(byte[] bytes, Object classData, boo
22132215 {
22142216 Objects .requireNonNull (bytes );
22152217 Objects .requireNonNull (classData );
2216- Objects .requireNonNull (options );
2218+
2219+ int flags = ClassOption .optionsToFlag (options );
22172220
22182221 ensureDefineClassPermission ();
22192222 if (!hasFullPrivilegeAccess ()) {
22202223 throw new IllegalAccessException (this + " does not have full privilege access" );
22212224 }
22222225
2223- return makeHiddenClassDefiner (bytes .clone (), Set . of ( options ), false )
2226+ return makeHiddenClassDefiner (bytes .clone (), false , flags )
22242227 .defineClassAsLookup (initialize , classData );
22252228 }
22262229
@@ -2366,7 +2369,7 @@ ClassDefiner makeClassDefiner(String name, byte[] bytes, ClassFileDumper dumper)
23662369 */
23672370 ClassDefiner makeHiddenClassDefiner (byte [] bytes , ClassFileDumper dumper ) {
23682371 ClassFile cf = ClassFile .newInstance (bytes , lookupClass ().getPackageName ());
2369- return makeHiddenClassDefiner (cf , Set . of (), false , dumper );
2372+ return makeHiddenClassDefiner (cf , false , dumper , 0 );
23702373 }
23712374
23722375 /**
@@ -2378,18 +2381,33 @@ ClassDefiner makeHiddenClassDefiner(byte[] bytes, ClassFileDumper dumper) {
23782381 * before calling this factory method.
23792382 *
23802383 * @param bytes class bytes
2381- * @param options class options
2384+ * @param flags class option flag mask
23822385 * @param accessVmAnnotations true to give the hidden class access to VM annotations
23832386 * @return ClassDefiner that defines a hidden class of the given bytes and options
23842387 *
23852388 * @throws IllegalArgumentException if {@code bytes} is not a class or interface or
23862389 * {@code bytes} denotes a class in a different package than the lookup class
23872390 */
23882391 private ClassDefiner makeHiddenClassDefiner (byte [] bytes ,
2389- Set < ClassOption > options ,
2390- boolean accessVmAnnotations ) {
2392+ boolean accessVmAnnotations ,
2393+ int flags ) {
23912394 ClassFile cf = ClassFile .newInstance (bytes , lookupClass ().getPackageName ());
2392- return makeHiddenClassDefiner (cf , options , accessVmAnnotations , defaultDumper ());
2395+ return makeHiddenClassDefiner (cf , accessVmAnnotations , defaultDumper (), flags );
2396+ }
2397+
2398+ /**
2399+ * Returns a ClassDefiner that creates a {@code Class} object of a hidden class
2400+ * from the given bytes and the given options. No package name check on the given bytes.
2401+ *
2402+ * @param name internal name that specifies the prefix of the hidden class
2403+ * @param bytes class bytes
2404+ * @param dumper dumper to write the given bytes to the dumper's output directory
2405+ * @return ClassDefiner that defines a hidden class of the given bytes and options.
2406+ */
2407+ ClassDefiner makeHiddenClassDefiner (String name , byte [] bytes , ClassFileDumper dumper ) {
2408+ Objects .requireNonNull (dumper );
2409+ // skip name and access flags validation
2410+ return makeHiddenClassDefiner (ClassFile .newInstanceNoCheck (name , bytes ), false , dumper , 0 );
23932411 }
23942412
23952413 /**
@@ -2398,30 +2416,30 @@ private ClassDefiner makeHiddenClassDefiner(byte[] bytes,
23982416 *
23992417 * @param name internal name that specifies the prefix of the hidden class
24002418 * @param bytes class bytes
2401- * @param options class options
2419+ * @param flags class options flag mask
24022420 * @param dumper dumper to write the given bytes to the dumper's output directory
24032421 * @return ClassDefiner that defines a hidden class of the given bytes and options.
24042422 */
2405- ClassDefiner makeHiddenClassDefiner (String name , byte [] bytes , Set < ClassOption > options , ClassFileDumper dumper ) {
2423+ ClassDefiner makeHiddenClassDefiner (String name , byte [] bytes , ClassFileDumper dumper , int flags ) {
24062424 Objects .requireNonNull (dumper );
24072425 // skip name and access flags validation
2408- return makeHiddenClassDefiner (ClassFile .newInstanceNoCheck (name , bytes ), options , false , dumper );
2426+ return makeHiddenClassDefiner (ClassFile .newInstanceNoCheck (name , bytes ), false , dumper , flags );
24092427 }
24102428
24112429 /**
24122430 * Returns a ClassDefiner that creates a {@code Class} object of a hidden class
24132431 * from the given class file and options.
24142432 *
24152433 * @param cf ClassFile
2416- * @param options class options
2434+ * @param flags class option flag mask
24172435 * @param accessVmAnnotations true to give the hidden class access to VM annotations
24182436 * @param dumper dumper to write the given bytes to the dumper's output directory
24192437 */
24202438 private ClassDefiner makeHiddenClassDefiner (ClassFile cf ,
2421- Set <ClassOption > options ,
24222439 boolean accessVmAnnotations ,
2423- ClassFileDumper dumper ) {
2424- int flags = HIDDEN_CLASS | ClassOption .optionsToFlag (options );
2440+ ClassFileDumper dumper ,
2441+ int flags ) {
2442+ flags |= HIDDEN_CLASS ;
24252443 if (accessVmAnnotations | VM .isSystemDomainLoader (lookupClass .getClassLoader ())) {
24262444 // jdk.internal.vm.annotations are permitted for classes
24272445 // defined to boot loader and platform loader
0 commit comments