elements() {
new ObjectStreamField("permissions", Vector.class),
};
- /**
- * @serialData "permissions" field (a Vector containing the FilePermissions).
- */
/**
* Writes the contents of the perms field out as a Vector for
* serialization compatibility with earlier releases.
+ * @serialData "permissions" field (a Vector containing the FilePermissions).
*
* @param out the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java
index dbc4b365944..dff50fd7be7 100644
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
@@ -1033,7 +1033,7 @@ public PutField() {}
* calling the {@link java.io.ObjectOutputStream#writeFields()}
* method.
*/
- @Deprecated
+ @Deprecated(forRemoval = true, since = "1.4")
public abstract void write(ObjectOutput out) throws IOException;
}
diff --git a/src/java.base/share/classes/java/io/ObjectStreamConstants.java b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
index d8ebbd23e73..4f06ba7f89e 100644
--- a/src/java.base/share/classes/java/io/ObjectStreamConstants.java
+++ b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
@@ -139,7 +139,7 @@ public interface ObjectStreamConstants {
static final int baseWireHandle = 0x7e0000;
- /******************************************************/
+ /* ****************************************************/
/* Bit masks for ObjectStreamClass flag.*/
/**
diff --git a/src/java.base/share/classes/java/io/RandomAccessFile.java b/src/java.base/share/classes/java/io/RandomAccessFile.java
index 5a1c87eb1f7..ee7b90ea71a 100644
--- a/src/java.base/share/classes/java/io/RandomAccessFile.java
+++ b/src/java.base/share/classes/java/io/RandomAccessFile.java
@@ -71,6 +71,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
private final FileDescriptor fd;
private final boolean rw;
+ private final boolean sync; // O_SYNC or O_DSYNC
/**
* The path of the referenced file
@@ -229,21 +230,25 @@ private RandomAccessFile(File file, String mode, boolean openAndDelete)
int imode = -1;
boolean rw = false;
+ boolean sync = false;
if (mode.equals("r"))
imode = O_RDONLY;
else if (mode.startsWith("rw")) {
imode = O_RDWR;
rw = true;
if (mode.length() > 2) {
- if (mode.equals("rws"))
+ if (mode.equals("rws")) {
imode |= O_SYNC;
- else if (mode.equals("rwd"))
+ sync = true;
+ } else if (mode.equals("rwd")) {
imode |= O_DSYNC;
- else
+ sync = true;
+ } else
imode = -1;
}
}
this.rw = rw;
+ this.sync = sync;
if (openAndDelete)
imode |= O_TEMPORARY;
@@ -308,8 +313,8 @@ public final FileChannel getChannel() {
synchronized (this) {
fc = this.channel;
if (fc == null) {
- this.channel = fc = FileChannelImpl.open(fd, path, true,
- rw, false, this);
+ fc = FileChannelImpl.open(fd, path, true, rw, sync, false, this);
+ this.channel = fc;
if (closed) {
try {
fc.close();
@@ -350,12 +355,7 @@ private native void open0(String name, int mode)
* defined above
*/
private void open(String name, int mode) throws FileNotFoundException {
- long comp = Blocker.begin();
- try {
- open0(name, mode);
- } finally {
- Blocker.end(comp);
- }
+ open0(name, mode);
}
// 'Read' primitives
@@ -376,12 +376,7 @@ private void open(String name, int mode) throws FileNotFoundException {
* end-of-file has been reached.
*/
public int read() throws IOException {
- long comp = Blocker.begin();
- try {
- return read0();
- } finally {
- Blocker.end(comp);
- }
+ return read0();
}
private native int read0() throws IOException;
@@ -394,12 +389,7 @@ public int read() throws IOException {
* @throws IOException If an I/O error has occurred.
*/
private int readBytes(byte[] b, int off, int len) throws IOException {
- long comp = Blocker.begin();
- try {
- return readBytes0(b, off, len);
- } finally {
- Blocker.end(comp);
- }
+ return readBytes0(b, off, len);
}
private native int readBytes0(byte[] b, int off, int len) throws IOException;
@@ -547,11 +537,11 @@ public int skipBytes(int n) throws IOException {
* @throws IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(sync);
try {
write0(b);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
}
@@ -566,11 +556,11 @@ public void write(int b) throws IOException {
* @throws IOException If an I/O error has occurred.
*/
private void writeBytes(byte[] b, int off, int len) throws IOException {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(sync);
try {
writeBytes0(b, off, len);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
}
@@ -630,12 +620,7 @@ public void seek(long pos) throws IOException {
if (pos < 0) {
throw new IOException("Negative seek offset");
}
- long comp = Blocker.begin();
- try {
- seek0(pos);
- } finally {
- Blocker.end(comp);
- }
+ seek0(pos);
}
private native void seek0(long pos) throws IOException;
@@ -647,12 +632,7 @@ public void seek(long pos) throws IOException {
* @throws IOException if an I/O error occurs.
*/
public long length() throws IOException {
- long comp = Blocker.begin();
- try {
- return length0();
- } finally {
- Blocker.end(comp);
- }
+ return length0();
}
private native long length0() throws IOException;
@@ -684,12 +664,7 @@ public long length() throws IOException {
* @since 1.2
*/
public void setLength(long newLength) throws IOException {
- long comp = Blocker.begin();
- try {
- setLength0(newLength);
- } finally {
- Blocker.end(comp);
- }
+ setLength0(newLength);
}
private native void setLength0(long newLength) throws IOException;
diff --git a/src/java.base/share/classes/java/io/Serializable.java b/src/java.base/share/classes/java/io/Serializable.java
index 07836c38e58..cf04ba2e60c 100644
--- a/src/java.base/share/classes/java/io/Serializable.java
+++ b/src/java.base/share/classes/java/io/Serializable.java
@@ -68,7 +68,7 @@
*
*
* private void writeObject(java.io.ObjectOutputStream out)
- * throws IOException
+ * throws IOException;
* private void readObject(java.io.ObjectInputStream in)
* throws IOException, ClassNotFoundException;
* private void readObjectNoData()
diff --git a/src/java.base/share/classes/java/lang/FdLibm.java b/src/java.base/share/classes/java/lang/FdLibm.java
index dd79ee82863..70d728a16db 100644
--- a/src/java.base/share/classes/java/lang/FdLibm.java
+++ b/src/java.base/share/classes/java/lang/FdLibm.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3005,7 +3005,6 @@ static double compute(double x) {
hx = __HI(x); // high word of x
xsb = hx & SIGN_BIT; // sign bit of x
- y = Math.abs(x);
hx &= EXP_SIGNIF_BITS; // high word of |x|
// filter out huge and non-finite argument
diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java
index 74b9d90b0ae..3ba5347ab8b 100644
--- a/src/java.base/share/classes/java/lang/Object.java
+++ b/src/java.base/share/classes/java/lang/Object.java
@@ -374,16 +374,21 @@ public final void wait() throws InterruptedException {
* @see #wait(long, int)
*/
public final void wait(long timeoutMillis) throws InterruptedException {
- long comp = Blocker.begin();
+ if (!Thread.currentThread().isVirtual()) {
+ wait0(timeoutMillis);
+ return;
+ }
+
+ // virtual thread waiting
+ boolean attempted = Blocker.begin();
try {
wait0(timeoutMillis);
} catch (InterruptedException e) {
- Thread thread = Thread.currentThread();
- if (thread.isVirtual())
- thread.getAndClearInterrupt();
+ // virtual thread's interrupt status needs to be cleared
+ Thread.currentThread().getAndClearInterrupt();
throw e;
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
}
diff --git a/src/java.base/share/classes/java/lang/Process.java b/src/java.base/share/classes/java/lang/Process.java
index 5b926e35729..f9762ffbcdb 100644
--- a/src/java.base/share/classes/java/lang/Process.java
+++ b/src/java.base/share/classes/java/lang/Process.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
package java.lang;
+import jdk.internal.misc.Blocker;
import jdk.internal.util.StaticProperty;
import java.io.*;
@@ -839,6 +840,75 @@ public long skip(long n) throws IOException {
return n - remaining;
}
+
+ @Override
+ public int read() throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read();
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read(b, off, len);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+ }
+
+ /**
+ * An output stream for a subprocess pipe.
+ */
+ static class PipeOutputStream extends FileOutputStream {
+ PipeOutputStream(FileDescriptor fd) {
+ super(fd);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b, off, len);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
}
/**
diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index b668a1697b7..a24689e57fb 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -72,6 +72,7 @@
import java.util.stream.Stream;
import jdk.internal.logger.LoggerFinderLoader.TemporaryLoggerFinder;
+import jdk.internal.misc.Blocker;
import jdk.internal.misc.CarrierThreadLocal;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.StaticProperty;
@@ -2191,9 +2192,9 @@ private static void initPhase1() {
lineSeparator = props.getProperty("line.separator");
- FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
- FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
- FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
+ FileInputStream fdIn = new In(FileDescriptor.in);
+ FileOutputStream fdOut = new Out(FileDescriptor.out);
+ FileOutputStream fdErr = new Out(FileDescriptor.err);
initialIn = new BufferedInputStream(fdIn);
setIn0(initialIn);
// stdout/err.encoding are set when the VM is associated with the terminal,
@@ -2218,6 +2219,83 @@ private static void initPhase1() {
VM.initLevel(1);
}
+ /**
+ * System.in.
+ */
+ private static class In extends FileInputStream {
+ In(FileDescriptor fd) {
+ super(fd);
+ }
+
+ @Override
+ public int read() throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read();
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ return super.read(b, off, len);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+ }
+
+ /**
+ * System.out/System.err wrap this output stream.
+ */
+ private static class Out extends FileOutputStream {
+ Out(FileDescriptor fd) {
+ super(fd);
+ }
+
+ public void write(int b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ boolean attempted = Blocker.begin();
+ try {
+ super.write(b, off, len);
+ } finally {
+ Blocker.end(attempted);
+ }
+ }
+ }
+
// @see #initPhase2()
static ModuleLayer bootLayer;
diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java
index 8e14c829d37..40469f2b8d6 100644
--- a/src/java.base/share/classes/java/lang/VirtualThread.java
+++ b/src/java.base/share/classes/java/lang/VirtualThread.java
@@ -466,6 +466,11 @@ private boolean yieldContinuation() {
private void afterYield() {
assert carrierThread == null;
+ // re-adjust parallelism if the virtual thread yielded when compensating
+ if (currentThread() instanceof CarrierThread ct) {
+ ct.endBlocking();
+ }
+
int s = state();
// LockSupport.park/parkNanos
@@ -1186,9 +1191,6 @@ private void setCarrierThread(Thread carrier) {
@IntrinsicCandidate
private static native void notifyJvmtiDisableSuspend(boolean enter);
- @IntrinsicCandidate
- private native void notifyJvmtiDisableSuspend(boolean enter);
-
private static native void registerNatives();
static {
registerNatives();
diff --git a/src/java.base/share/classes/java/lang/classfile/BufWriter.java b/src/java.base/share/classes/java/lang/classfile/BufWriter.java
index bab8ebda4b8..f178b6b2db0 100644
--- a/src/java.base/share/classes/java/lang/classfile/BufWriter.java
+++ b/src/java.base/share/classes/java/lang/classfile/BufWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -124,6 +124,7 @@ public sealed interface BufWriter
* @param arr the byte array
* @param start the offset within the byte array of the range
* @param length the length of the range
+ * @throws IndexOutOfBoundsException if range is outside of the array bounds
*/
void writeBytes(byte[] arr, int start, int length);
@@ -134,6 +135,7 @@ public sealed interface BufWriter
* @param offset the offset at which to patch
* @param size the size of the integer value being written, in bytes
* @param value the integer value
+ * @throws IndexOutOfBoundsException if patched int is outside of bounds
*/
void patchInt(int offset, int size, int value);
@@ -152,7 +154,7 @@ public sealed interface BufWriter
* to the buffer
*
* @param entry the constant pool entry
- * @throws NullPointerException if the entry is null
+ * @throws IllegalArgumentException if the entry has invalid index
*/
void writeIndex(PoolEntry entry);
@@ -161,6 +163,7 @@ public sealed interface BufWriter
* to the buffer, or zero if the entry is null
*
* @param entry the constant pool entry
+ * @throws IllegalArgumentException if the entry has invalid index
*/
void writeIndexOrZero(PoolEntry entry);
@@ -180,6 +183,7 @@ public sealed interface BufWriter
* entry in the list.
*
* @param list the list of entries
+ * @throws IllegalArgumentException if any entry has invalid index
*/
void writeListIndices(List extends PoolEntry> list);
@@ -199,6 +203,7 @@ public sealed interface BufWriter
* @param array the byte array
* @param bufferOffset the offset into the array at which to write the
* contents of the buffer
+ * @throws IndexOutOfBoundsException if copying outside of the array bounds
*/
void copyTo(byte[] array, int bufferOffset);
}
diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFile.java b/src/java.base/share/classes/java/lang/classfile/ClassFile.java
index 39ace9e2ac8..32edc3c680a 100644
--- a/src/java.base/share/classes/java/lang/classfile/ClassFile.java
+++ b/src/java.base/share/classes/java/lang/classfile/ClassFile.java
@@ -1478,9 +1478,6 @@ default List verify(Path path) throws IOException {
/** The class major version of JAVA_22. */
int JAVA_22_VERSION = 66;
- /** 67 */
- int JAVA_23_VERSION = 67;
-
/**
* The class major version of JAVA_23.
* @since 23
diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java
index 544d7322c1c..e954be079fa 100644
--- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java
+++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java
@@ -212,8 +212,7 @@ default CodeBuilder block(Consumer handler) {
child.start();
handler.accept(child);
child.end();
- labelBinding(breakLabel);
- return this;
+ return labelBinding(breakLabel);
}
/**
@@ -253,12 +252,11 @@ default CodeBuilder ifThen(Opcode opcode,
Label breakLabel = newLabel();
BlockCodeBuilderImpl thenBlock = new BlockCodeBuilderImpl(this, breakLabel);
- branchInstruction(BytecodeHelpers.reverseBranchOpcode(opcode), thenBlock.endLabel());
+ branch(BytecodeHelpers.reverseBranchOpcode(opcode), thenBlock.endLabel());
thenBlock.start();
thenHandler.accept(thenBlock);
thenBlock.end();
- labelBinding(breakLabel);
- return this;
+ return labelBinding(breakLabel);
}
/**
@@ -305,17 +303,16 @@ default CodeBuilder ifThenElse(Opcode opcode,
Label breakLabel = newLabel();
BlockCodeBuilderImpl thenBlock = new BlockCodeBuilderImpl(this, breakLabel);
BlockCodeBuilderImpl elseBlock = new BlockCodeBuilderImpl(this, breakLabel);
- branchInstruction(BytecodeHelpers.reverseBranchOpcode(opcode), elseBlock.startLabel());
+ branch(BytecodeHelpers.reverseBranchOpcode(opcode), elseBlock.startLabel());
thenBlock.start();
thenHandler.accept(thenBlock);
if (thenBlock.reachable())
- thenBlock.branchInstruction(Opcode.GOTO, thenBlock.breakLabel());
+ thenBlock.branch(Opcode.GOTO, thenBlock.breakLabel());
thenBlock.end();
elseBlock.start();
elseHandler.accept(elseBlock);
elseBlock.end();
- labelBinding(breakLabel);
- return this;
+ return labelBinding(breakLabel);
}
/**
@@ -416,10 +413,10 @@ default CodeBuilder trying(Consumer tryHandler,
* @param tk the load type
* @param slot the local variable slot
* @return this builder
+ * @since 23
*/
- default CodeBuilder loadInstruction(TypeKind tk, int slot) {
- with(LoadInstruction.of(tk, slot));
- return this;
+ default CodeBuilder loadLocal(TypeKind tk, int slot) {
+ return with(LoadInstruction.of(tk, slot));
}
/**
@@ -427,21 +424,10 @@ default CodeBuilder loadInstruction(TypeKind tk, int slot) {
* @param tk the store type
* @param slot the local variable slot
* @return this builder
+ * @since 23
*/
- default CodeBuilder storeInstruction(TypeKind tk, int slot) {
- with(StoreInstruction.of(tk, slot));
- return this;
- }
-
- /**
- * Generate an instruction to increment a local variable by a constant
- * @param slot the local variable slot
- * @param val the increment value
- * @return this builder
- */
- default CodeBuilder incrementInstruction(int slot, int val) {
- with(IncrementInstruction.of(slot, val));
- return this;
+ default CodeBuilder storeLocal(TypeKind tk, int slot) {
+ return with(StoreInstruction.of(tk, slot));
}
/**
@@ -450,53 +436,20 @@ default CodeBuilder incrementInstruction(int slot, int val) {
* @param op the branch opcode
* @param target the branch target
* @return this builder
+ * @since 23
*/
- default CodeBuilder branchInstruction(Opcode op, Label target) {
- with(BranchInstruction.of(op, target));
- return this;
- }
-
- /**
- * Generate an instruction to access a jump table by key match and jump
- * @param defaultTarget the default jump target
- * @param cases the switch cases
- * @return this builder
- */
- default CodeBuilder lookupSwitchInstruction(Label defaultTarget, List cases) {
- with(LookupSwitchInstruction.of(defaultTarget, cases));
- return this;
- }
-
- /**
- * Generate an instruction to access a jump table by index and jump
- * @param lowValue the low key value
- * @param highValue the high key value
- * @param defaultTarget the default jump target
- * @param cases the switch cases
- * @return this builder
- */
- default CodeBuilder tableSwitchInstruction(int lowValue, int highValue, Label defaultTarget, List cases) {
- with(TableSwitchInstruction.of(lowValue, highValue, defaultTarget, cases));
- return this;
+ default CodeBuilder branch(Opcode op, Label target) {
+ return with(BranchInstruction.of(op, target));
}
/**
* Generate return instruction
* @param tk the return type
* @return this builder
+ * @since 23
*/
- default CodeBuilder returnInstruction(TypeKind tk) {
- with(ReturnInstruction.of(tk));
- return this;
- }
-
- /**
- * Generate an instruction to throw an exception or error
- * @return this builder
- */
- default CodeBuilder throwInstruction() {
- with(ThrowInstruction.of());
- return this;
+ default CodeBuilder return_(TypeKind tk) {
+ return with(ReturnInstruction.of(tk));
}
/**
@@ -505,10 +458,10 @@ default CodeBuilder throwInstruction() {
* @param opcode the field access opcode
* @param ref the field reference
* @return this builder
+ * @since 23
*/
- default CodeBuilder fieldInstruction(Opcode opcode, FieldRefEntry ref) {
- with(FieldInstruction.of(opcode, ref));
- return this;
+ default CodeBuilder fieldAccess(Opcode opcode, FieldRefEntry ref) {
+ return with(FieldInstruction.of(opcode, ref));
}
/**
@@ -519,9 +472,10 @@ default CodeBuilder fieldInstruction(Opcode opcode, FieldRefEntry ref) {
* @param name the field name
* @param type the field type
* @return this builder
+ * @since 23
*/
- default CodeBuilder fieldInstruction(Opcode opcode, ClassDesc owner, String name, ClassDesc type) {
- return fieldInstruction(opcode, constantPool().fieldRefEntry(owner, name, type));
+ default CodeBuilder fieldAccess(Opcode opcode, ClassDesc owner, String name, ClassDesc type) {
+ return fieldAccess(opcode, constantPool().fieldRefEntry(owner, name, type));
}
/**
@@ -530,8 +484,9 @@ default CodeBuilder fieldInstruction(Opcode opcode, ClassDesc owner, String name
* @param opcode the invoke opcode
* @param ref the interface method or method reference
* @return this builder
+ * @since 23
*/
- default CodeBuilder invokeInstruction(Opcode opcode, MemberRefEntry ref) {
+ default CodeBuilder invoke(Opcode opcode, MemberRefEntry ref) {
return with(InvokeInstruction.of(opcode, ref));
}
@@ -544,191 +499,101 @@ default CodeBuilder invokeInstruction(Opcode opcode, MemberRefEntry ref) {
* @param desc the method type
* @param isInterface the interface method invocation indication
* @return this builder
+ * @since 23
*/
- default CodeBuilder invokeInstruction(Opcode opcode, ClassDesc owner, String name, MethodTypeDesc desc, boolean isInterface) {
- return invokeInstruction(opcode,
+ default CodeBuilder invoke(Opcode opcode, ClassDesc owner, String name, MethodTypeDesc desc, boolean isInterface) {
+ return invoke(opcode,
isInterface ? constantPool().interfaceMethodRefEntry(owner, name, desc)
: constantPool().methodRefEntry(owner, name, desc));
}
- /**
- * Generate an instruction to invoke a dynamically-computed call site
- * @param ref the dynamic call site
- * @return this builder
- */
- default CodeBuilder invokeDynamicInstruction(InvokeDynamicEntry ref) {
- with(InvokeDynamicInstruction.of(ref));
- return this;
- }
-
- /**
- * Generate an instruction to invoke a dynamically-computed call site
- * @param desc the dynamic call site
- * @return this builder
- */
- default CodeBuilder invokeDynamicInstruction(DynamicCallSiteDesc desc) {
- MethodHandleEntry bsMethod = handleDescToHandleInfo(constantPool(), (DirectMethodHandleDesc) desc.bootstrapMethod());
- var cpArgs = desc.bootstrapArgs();
- List bsArguments = new ArrayList<>(cpArgs.length);
- for (var constantValue : cpArgs) {
- bsArguments.add(BytecodeHelpers.constantEntry(constantPool(), constantValue));
- }
- BootstrapMethodEntry bm = constantPool().bsmEntry(bsMethod, bsArguments);
- NameAndTypeEntry nameAndType = constantPool().nameAndTypeEntry(desc.invocationName(), desc.invocationType());
- invokeDynamicInstruction(constantPool().invokeDynamicEntry(bm, nameAndType));
- return this;
- }
-
- /**
- * Generate an instruction to create a new object
- * @param type the object type
- * @return this builder
- */
- default CodeBuilder newObjectInstruction(ClassEntry type) {
- with(NewObjectInstruction.of(type));
- return this;
- }
-
- /**
- * Generate an instruction to create a new object
- * @param type the object type
- * @return this builder
- * @throws IllegalArgumentException if {@code type} represents a primitive type
- */
- default CodeBuilder newObjectInstruction(ClassDesc type) {
- return newObjectInstruction(constantPool().classEntry(type));
- }
-
- /**
- * Generate an instruction to create a new array of a primitive type
- * @param typeKind the primitive component type
- * @return this builder
- */
- default CodeBuilder newPrimitiveArrayInstruction(TypeKind typeKind) {
- with(NewPrimitiveArrayInstruction.of(typeKind));
- return this;
- }
-
- /**
- * Generate an instruction to create a new array of reference
- * @param type the component type
- * @return this builder
- */
- default CodeBuilder newReferenceArrayInstruction(ClassEntry type) {
- with(NewReferenceArrayInstruction.of(type));
- return this;
- }
-
- /**
- * Generate an instruction to create a new array of reference
- * @param type the component type
- * @return this builder
- * @throws IllegalArgumentException if {@code type} represents a primitive type
- */
- default CodeBuilder newReferenceArrayInstruction(ClassDesc type) {
- return newReferenceArrayInstruction(constantPool().classEntry(type));
- }
-
- /**
- * Generate an instruction to create a new multidimensional array
- * @param dimensions the number of dimensions
- * @param type the array type
- * @return this builder
- */
- default CodeBuilder newMultidimensionalArrayInstruction(int dimensions,
- ClassEntry type) {
- with(NewMultiArrayInstruction.of(type, dimensions));
- return this;
- }
-
- /**
- * Generate an instruction to create a new multidimensional array
- * @param dimensions the number of dimensions
- * @param type the array type
- * @return this builder
- */
- default CodeBuilder newMultidimensionalArrayInstruction(int dimensions,
- ClassDesc type) {
- return newMultidimensionalArrayInstruction(dimensions, constantPool().classEntry(type));
- }
-
/**
* Generate an instruction to load from an array
* @param tk the array element type
* @return this builder
+ * @since 23
*/
- default CodeBuilder arrayLoadInstruction(TypeKind tk) {
+ default CodeBuilder arrayLoad(TypeKind tk) {
Opcode opcode = BytecodeHelpers.arrayLoadOpcode(tk);
- with(ArrayLoadInstruction.of(opcode));
- return this;
+ return with(ArrayLoadInstruction.of(opcode));
}
/**
* Generate an instruction to store into an array
* @param tk the array element type
* @return this builder
+ * @since 23
*/
- default CodeBuilder arrayStoreInstruction(TypeKind tk) {
+ default CodeBuilder arrayStore(TypeKind tk) {
Opcode opcode = BytecodeHelpers.arrayStoreOpcode(tk);
- with(ArrayStoreInstruction.of(opcode));
- return this;
- }
-
- /**
- * Generate a type checking instruction
- * @see Opcode.Kind#TYPE_CHECK
- * @param opcode the type check instruction opcode
- * @param type the type
- * @return this builder
- */
- default CodeBuilder typeCheckInstruction(Opcode opcode,
- ClassEntry type) {
- with(TypeCheckInstruction.of(opcode, type));
- return this;
- }
-
- /**
- * Generate a type checking instruction
- * @see Opcode.Kind#TYPE_CHECK
- * @param opcode the type check instruction opcode
- * @param type the type
- * @return this builder
- */
- default CodeBuilder typeCheckInstruction(Opcode opcode, ClassDesc type) {
- return typeCheckInstruction(opcode, constantPool().classEntry(type));
+ return with(ArrayStoreInstruction.of(opcode));
}
/**
- * Generate a type converting instruction
+ * Generate instruction(s) to convert {@code fromType} to {@code toType}
* @param fromType the source type
* @param toType the target type
* @return this builder
- */
- default CodeBuilder convertInstruction(TypeKind fromType, TypeKind toType) {
- with(ConvertInstruction.of(fromType, toType));
- return this;
- }
-
- /**
- * Generate a stack manipulating instruction
- * @param opcode the stack instruction opcode
- * @see Opcode.Kind#STACK
- * @return this builder
- */
- default CodeBuilder stackInstruction(Opcode opcode) {
- with(StackInstruction.of(opcode));
- return this;
- }
-
- /**
- * Generate an operator instruction
- * @see Opcode.Kind#OPERATOR
- * @param opcode the operator instruction opcode
- * @return this builder
- */
- default CodeBuilder operatorInstruction(Opcode opcode) {
- with(OperatorInstruction.of(opcode));
- return this;
+ * @throws IllegalArgumentException for conversions of {@code VoidType} or {@code ReferenceType}
+ * @since 23
+ */
+ default CodeBuilder conversion(TypeKind fromType, TypeKind toType) {
+ return switch (fromType) {
+ case IntType, ByteType, CharType, ShortType, BooleanType ->
+ switch (toType) {
+ case IntType -> this;
+ case LongType -> i2l();
+ case DoubleType -> i2d();
+ case FloatType -> i2f();
+ case ByteType -> i2b();
+ case CharType -> i2c();
+ case ShortType -> i2s();
+ case BooleanType -> iconst_1().iand();
+ case VoidType, ReferenceType ->
+ throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
+ };
+ case LongType ->
+ switch (toType) {
+ case IntType -> l2i();
+ case LongType -> this;
+ case DoubleType -> l2d();
+ case FloatType -> l2f();
+ case ByteType -> l2i().i2b();
+ case CharType -> l2i().i2c();
+ case ShortType -> l2i().i2s();
+ case BooleanType -> l2i().iconst_1().iand();
+ case VoidType, ReferenceType ->
+ throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
+ };
+ case DoubleType ->
+ switch (toType) {
+ case IntType -> d2i();
+ case LongType -> d2l();
+ case DoubleType -> this;
+ case FloatType -> d2f();
+ case ByteType -> d2i().i2b();
+ case CharType -> d2i().i2c();
+ case ShortType -> d2i().i2s();
+ case BooleanType -> d2i().iconst_1().iand();
+ case VoidType, ReferenceType ->
+ throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
+ };
+ case FloatType ->
+ switch (toType) {
+ case IntType -> f2i();
+ case LongType -> f2l();
+ case DoubleType -> f2d();
+ case FloatType -> this;
+ case ByteType -> f2i().i2b();
+ case CharType -> f2i().i2c();
+ case ShortType -> f2i().i2s();
+ case BooleanType -> f2i().iconst_1().iand();
+ case VoidType, ReferenceType ->
+ throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
+ };
+ case VoidType, ReferenceType ->
+ throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
+ };
}
/**
@@ -737,8 +602,9 @@ default CodeBuilder operatorInstruction(Opcode opcode) {
* @param opcode the constant instruction opcode
* @param value the constant value
* @return this builder
+ * @since 23
*/
- default CodeBuilder constantInstruction(Opcode opcode, ConstantDesc value) {
+ default CodeBuilder loadConstant(Opcode opcode, ConstantDesc value) {
BytecodeHelpers.validateValue(opcode, value);
return with(switch (opcode) {
case SIPUSH, BIPUSH -> ConstantInstruction.ofArgument(opcode, ((Number)value).intValue());
@@ -751,8 +617,9 @@ default CodeBuilder constantInstruction(Opcode opcode, ConstantDesc value) {
* Generate an instruction pushing a constant onto the operand stack
* @param value the constant value
* @return this builder
+ * @since 23
*/
- default CodeBuilder constantInstruction(ConstantDesc value) {
+ default CodeBuilder loadConstant(ConstantDesc value) {
//avoid switch expressions here
if (value == null || value == ConstantDescs.NULL)
return aconst_null();
@@ -785,32 +652,12 @@ default CodeBuilder constantInstruction(ConstantDesc value) {
return ldc(value);
}
- /**
- * Generate a monitor instruction
- * @see Opcode.Kind#MONITOR
- * @param opcode the monitor instruction opcode
- * @return this builder
- */
- default CodeBuilder monitorInstruction(Opcode opcode) {
- with(MonitorInstruction.of(opcode));
- return null;
- }
-
- /**
- * Generate a do nothing instruction
- * @return this builder
- */
- default CodeBuilder nopInstruction() {
- with(NopInstruction.of());
- return this;
- }
-
/**
* Generate a do nothing instruction
* @return this builder
*/
default CodeBuilder nop() {
- return nopInstruction();
+ return with(NopInstruction.of());
}
// Base pseudo-instruction builder methods
@@ -831,8 +678,7 @@ default Label newBoundLabel() {
* @return this builder
*/
default CodeBuilder labelBinding(Label label) {
- with((LabelImpl) label);
- return this;
+ return with((LabelImpl) label);
}
/**
@@ -841,8 +687,7 @@ default CodeBuilder labelBinding(Label label) {
* @return this builder
*/
default CodeBuilder lineNumber(int line) {
- with(LineNumber.of(line));
- return this;
+ return with(LineNumber.of(line));
}
/**
@@ -854,8 +699,7 @@ default CodeBuilder lineNumber(int line) {
* @return this builder
*/
default CodeBuilder exceptionCatch(Label start, Label end, Label handler, ClassEntry catchType) {
- with(ExceptionCatch.of(handler, start, end, Optional.of(catchType)));
- return this;
+ return with(ExceptionCatch.of(handler, start, end, Optional.of(catchType)));
}
/**
@@ -867,8 +711,7 @@ default CodeBuilder exceptionCatch(Label start, Label end, Label handler, ClassE
* @return this builder
*/
default CodeBuilder exceptionCatch(Label start, Label end, Label handler, Optional catchType) {
- with(ExceptionCatch.of(handler, start, end, catchType));
- return this;
+ return with(ExceptionCatch.of(handler, start, end, catchType));
}
/**
@@ -892,8 +735,7 @@ default CodeBuilder exceptionCatch(Label start, Label end, Label handler, ClassD
* @return this builder
*/
default CodeBuilder exceptionCatchAll(Label start, Label end, Label handler) {
- with(ExceptionCatch.of(handler, start, end));
- return this;
+ return with(ExceptionCatch.of(handler, start, end));
}
/**
@@ -906,8 +748,7 @@ default CodeBuilder exceptionCatchAll(Label start, Label end, Label handler) {
* @return this builder
*/
default CodeBuilder characterRange(Label startScope, Label endScope, int characterRangeStart, int characterRangeEnd, int flags) {
- with(CharacterRange.of(startScope, endScope, characterRangeStart, characterRangeEnd, flags));
- return this;
+ return with(CharacterRange.of(startScope, endScope, characterRangeStart, characterRangeEnd, flags));
}
/**
@@ -920,8 +761,7 @@ default CodeBuilder characterRange(Label startScope, Label endScope, int charact
* @return this builder
*/
default CodeBuilder localVariable(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry, Label startScope, Label endScope) {
- with(LocalVariable.of(slot, nameEntry, descriptorEntry, startScope, endScope));
- return this;
+ return with(LocalVariable.of(slot, nameEntry, descriptorEntry, startScope, endScope));
}
/**
@@ -950,8 +790,7 @@ default CodeBuilder localVariable(int slot, String name, ClassDesc descriptor, L
* @return this builder
*/
default CodeBuilder localVariableType(int slot, Utf8Entry nameEntry, Utf8Entry signatureEntry, Label startScope, Label endScope) {
- with(LocalVariableType.of(slot, nameEntry, signatureEntry, startScope, endScope));
- return this;
+ return with(LocalVariableType.of(slot, nameEntry, signatureEntry, startScope, endScope));
}
/**
@@ -985,7 +824,7 @@ default CodeBuilder aconst_null() {
* @return this builder
*/
default CodeBuilder aaload() {
- return arrayLoadInstruction(TypeKind.ReferenceType);
+ return arrayLoad(TypeKind.ReferenceType);
}
/**
@@ -993,7 +832,7 @@ default CodeBuilder aaload() {
* @return this builder
*/
default CodeBuilder aastore() {
- return arrayStoreInstruction(TypeKind.ReferenceType);
+ return arrayStore(TypeKind.ReferenceType);
}
/**
@@ -1002,7 +841,7 @@ default CodeBuilder aastore() {
* @return this builder
*/
default CodeBuilder aload(int slot) {
- return loadInstruction(TypeKind.ReferenceType, slot);
+ return loadLocal(TypeKind.ReferenceType, slot);
}
/**
@@ -1011,7 +850,7 @@ default CodeBuilder aload(int slot) {
* @return this builder
*/
default CodeBuilder anewarray(ClassEntry classEntry) {
- return newReferenceArrayInstruction(classEntry);
+ return with(NewReferenceArrayInstruction.of(classEntry));
}
/**
@@ -1021,7 +860,7 @@ default CodeBuilder anewarray(ClassEntry classEntry) {
* @throws IllegalArgumentException if {@code className} represents a primitive type
*/
default CodeBuilder anewarray(ClassDesc className) {
- return newReferenceArrayInstruction(constantPool().classEntry(className));
+ return anewarray(constantPool().classEntry(className));
}
/**
@@ -1029,7 +868,7 @@ default CodeBuilder anewarray(ClassDesc className) {
* @return this builder
*/
default CodeBuilder areturn() {
- return returnInstruction(TypeKind.ReferenceType);
+ return return_(TypeKind.ReferenceType);
}
/**
@@ -1037,7 +876,7 @@ default CodeBuilder areturn() {
* @return this builder
*/
default CodeBuilder arraylength() {
- return operatorInstruction(Opcode.ARRAYLENGTH);
+ return with(OperatorInstruction.of(Opcode.ARRAYLENGTH));
}
/**
@@ -1046,7 +885,7 @@ default CodeBuilder arraylength() {
* @return this builder
*/
default CodeBuilder astore(int slot) {
- return storeInstruction(TypeKind.ReferenceType, slot);
+ return storeLocal(TypeKind.ReferenceType, slot);
}
/**
@@ -1054,7 +893,7 @@ default CodeBuilder astore(int slot) {
* @return this builder
*/
default CodeBuilder athrow() {
- return throwInstruction();
+ return with(ThrowInstruction.of());
}
/**
@@ -1062,7 +901,7 @@ default CodeBuilder athrow() {
* @return this builder
*/
default CodeBuilder baload() {
- return arrayLoadInstruction(TypeKind.ByteType);
+ return arrayLoad(TypeKind.ByteType);
}
/**
@@ -1070,7 +909,7 @@ default CodeBuilder baload() {
* @return this builder
*/
default CodeBuilder bastore() {
- return arrayStoreInstruction(TypeKind.ByteType);
+ return arrayStore(TypeKind.ByteType);
}
/**
@@ -1079,7 +918,7 @@ default CodeBuilder bastore() {
* @return this builder
*/
default CodeBuilder bipush(int b) {
- return constantInstruction(Opcode.BIPUSH, b);
+ return loadConstant(Opcode.BIPUSH, b);
}
/**
@@ -1087,7 +926,7 @@ default CodeBuilder bipush(int b) {
* @return this builder
*/
default CodeBuilder caload() {
- return arrayLoadInstruction(TypeKind.CharType);
+ return arrayLoad(TypeKind.CharType);
}
/**
@@ -1095,7 +934,7 @@ default CodeBuilder caload() {
* @return this builder
*/
default CodeBuilder castore() {
- return arrayStoreInstruction(TypeKind.CharType);
+ return arrayStore(TypeKind.CharType);
}
/**
@@ -1104,7 +943,7 @@ default CodeBuilder castore() {
* @return this builder
*/
default CodeBuilder checkcast(ClassEntry type) {
- return typeCheckInstruction(Opcode.CHECKCAST, type);
+ return with(TypeCheckInstruction.of(Opcode.CHECKCAST, type));
}
/**
@@ -1114,7 +953,7 @@ default CodeBuilder checkcast(ClassEntry type) {
* @throws IllegalArgumentException if {@code type} represents a primitive type
*/
default CodeBuilder checkcast(ClassDesc type) {
- return typeCheckInstruction(Opcode.CHECKCAST, type);
+ return checkcast(constantPool().classEntry(type));
}
/**
@@ -1122,7 +961,7 @@ default CodeBuilder checkcast(ClassDesc type) {
* @return this builder
*/
default CodeBuilder d2f() {
- return convertInstruction(TypeKind.DoubleType, TypeKind.FloatType);
+ return with(ConvertInstruction.of(Opcode.D2F));
}
/**
@@ -1130,7 +969,7 @@ default CodeBuilder d2f() {
* @return this builder
*/
default CodeBuilder d2i() {
- return convertInstruction(TypeKind.DoubleType, TypeKind.IntType);
+ return with(ConvertInstruction.of(Opcode.D2I));
}
/**
@@ -1138,7 +977,7 @@ default CodeBuilder d2i() {
* @return this builder
*/
default CodeBuilder d2l() {
- return convertInstruction(TypeKind.DoubleType, TypeKind.LongType);
+ return with(ConvertInstruction.of(Opcode.D2L));
}
/**
@@ -1146,7 +985,7 @@ default CodeBuilder d2l() {
* @return this builder
*/
default CodeBuilder dadd() {
- return operatorInstruction(Opcode.DADD);
+ return with(OperatorInstruction.of(Opcode.DADD));
}
/**
@@ -1154,7 +993,7 @@ default CodeBuilder dadd() {
* @return this builder
*/
default CodeBuilder daload() {
- return arrayLoadInstruction(TypeKind.DoubleType);
+ return arrayLoad(TypeKind.DoubleType);
}
/**
@@ -1162,7 +1001,7 @@ default CodeBuilder daload() {
* @return this builder
*/
default CodeBuilder dastore() {
- return arrayStoreInstruction(TypeKind.DoubleType);
+ return arrayStore(TypeKind.DoubleType);
}
/**
@@ -1170,7 +1009,7 @@ default CodeBuilder dastore() {
* @return this builder
*/
default CodeBuilder dcmpg() {
- return operatorInstruction(Opcode.DCMPG);
+ return with(OperatorInstruction.of(Opcode.DCMPG));
}
/**
@@ -1178,7 +1017,7 @@ default CodeBuilder dcmpg() {
* @return this builder
*/
default CodeBuilder dcmpl() {
- return operatorInstruction(Opcode.DCMPL);
+ return with(OperatorInstruction.of(Opcode.DCMPL));
}
/**
@@ -1202,7 +1041,7 @@ default CodeBuilder dconst_1() {
* @return this builder
*/
default CodeBuilder ddiv() {
- return operatorInstruction(Opcode.DDIV);
+ return with(OperatorInstruction.of(Opcode.DDIV));
}
/**
@@ -1211,7 +1050,7 @@ default CodeBuilder ddiv() {
* @return this builder
*/
default CodeBuilder dload(int slot) {
- return loadInstruction(TypeKind.DoubleType, slot);
+ return loadLocal(TypeKind.DoubleType, slot);
}
/**
@@ -1219,7 +1058,7 @@ default CodeBuilder dload(int slot) {
* @return this builder
*/
default CodeBuilder dmul() {
- return operatorInstruction(Opcode.DMUL);
+ return with(OperatorInstruction.of(Opcode.DMUL));
}
/**
@@ -1227,7 +1066,7 @@ default CodeBuilder dmul() {
* @return this builder
*/
default CodeBuilder dneg() {
- return operatorInstruction(Opcode.DNEG);
+ return with(OperatorInstruction.of(Opcode.DNEG));
}
/**
@@ -1235,7 +1074,7 @@ default CodeBuilder dneg() {
* @return this builder
*/
default CodeBuilder drem() {
- return operatorInstruction(Opcode.DREM);
+ return with(OperatorInstruction.of(Opcode.DREM));
}
/**
@@ -1243,7 +1082,7 @@ default CodeBuilder drem() {
* @return this builder
*/
default CodeBuilder dreturn() {
- return returnInstruction(TypeKind.DoubleType);
+ return return_(TypeKind.DoubleType);
}
/**
@@ -1252,7 +1091,7 @@ default CodeBuilder dreturn() {
* @return this builder
*/
default CodeBuilder dstore(int slot) {
- return storeInstruction(TypeKind.DoubleType, slot);
+ return storeLocal(TypeKind.DoubleType, slot);
}
/**
@@ -1260,7 +1099,7 @@ default CodeBuilder dstore(int slot) {
* @return this builder
*/
default CodeBuilder dsub() {
- return operatorInstruction(Opcode.DSUB);
+ return with(OperatorInstruction.of(Opcode.DSUB));
}
/**
@@ -1268,7 +1107,7 @@ default CodeBuilder dsub() {
* @return this builder
*/
default CodeBuilder dup() {
- return stackInstruction(Opcode.DUP);
+ return with(StackInstruction.of(Opcode.DUP));
}
/**
@@ -1276,7 +1115,7 @@ default CodeBuilder dup() {
* @return this builder
*/
default CodeBuilder dup2() {
- return stackInstruction(Opcode.DUP2);
+ return with(StackInstruction.of(Opcode.DUP2));
}
/**
@@ -1285,7 +1124,7 @@ default CodeBuilder dup2() {
* @return this builder
*/
default CodeBuilder dup2_x1() {
- return stackInstruction(Opcode.DUP2_X1);
+ return with(StackInstruction.of(Opcode.DUP2_X1));
}
/**
@@ -1294,7 +1133,7 @@ default CodeBuilder dup2_x1() {
* @return this builder
*/
default CodeBuilder dup2_x2() {
- return stackInstruction(Opcode.DUP2_X2);
+ return with(StackInstruction.of(Opcode.DUP2_X2));
}
/**
@@ -1302,7 +1141,7 @@ default CodeBuilder dup2_x2() {
* @return this builder
*/
default CodeBuilder dup_x1() {
- return stackInstruction(Opcode.DUP_X1);
+ return with(StackInstruction.of(Opcode.DUP_X1));
}
/**
@@ -1310,7 +1149,7 @@ default CodeBuilder dup_x1() {
* @return this builder
*/
default CodeBuilder dup_x2() {
- return stackInstruction(Opcode.DUP_X2);
+ return with(StackInstruction.of(Opcode.DUP_X2));
}
/**
@@ -1318,7 +1157,7 @@ default CodeBuilder dup_x2() {
* @return this builder
*/
default CodeBuilder f2d() {
- return convertInstruction(TypeKind.FloatType, TypeKind.DoubleType);
+ return with(ConvertInstruction.of(Opcode.F2D));
}
/**
@@ -1326,7 +1165,7 @@ default CodeBuilder f2d() {
* @return this builder
*/
default CodeBuilder f2i() {
- return convertInstruction(TypeKind.FloatType, TypeKind.IntType);
+ return with(ConvertInstruction.of(Opcode.F2I));
}
/**
@@ -1334,7 +1173,7 @@ default CodeBuilder f2i() {
* @return this builder
*/
default CodeBuilder f2l() {
- return convertInstruction(TypeKind.FloatType, TypeKind.LongType);
+ return with(ConvertInstruction.of(Opcode.F2L));
}
/**
@@ -1342,7 +1181,7 @@ default CodeBuilder f2l() {
* @return this builder
*/
default CodeBuilder fadd() {
- return operatorInstruction(Opcode.FADD);
+ return with(OperatorInstruction.of(Opcode.FADD));
}
/**
@@ -1350,7 +1189,7 @@ default CodeBuilder fadd() {
* @return this builder
*/
default CodeBuilder faload() {
- return arrayLoadInstruction(TypeKind.FloatType);
+ return arrayLoad(TypeKind.FloatType);
}
/**
@@ -1358,7 +1197,7 @@ default CodeBuilder faload() {
* @return this builder
*/
default CodeBuilder fastore() {
- return arrayStoreInstruction(TypeKind.FloatType);
+ return arrayStore(TypeKind.FloatType);
}
/**
@@ -1366,7 +1205,7 @@ default CodeBuilder fastore() {
* @return this builder
*/
default CodeBuilder fcmpg() {
- return operatorInstruction(Opcode.FCMPG);
+ return with(OperatorInstruction.of(Opcode.FCMPG));
}
/**
@@ -1374,7 +1213,7 @@ default CodeBuilder fcmpg() {
* @return this builder
*/
default CodeBuilder fcmpl() {
- return operatorInstruction(Opcode.FCMPL);
+ return with(OperatorInstruction.of(Opcode.FCMPL));
}
/**
@@ -1406,7 +1245,7 @@ default CodeBuilder fconst_2() {
* @return this builder
*/
default CodeBuilder fdiv() {
- return operatorInstruction(Opcode.FDIV);
+ return with(OperatorInstruction.of(Opcode.FDIV));
}
/**
@@ -1415,7 +1254,7 @@ default CodeBuilder fdiv() {
* @return this builder
*/
default CodeBuilder fload(int slot) {
- return loadInstruction(TypeKind.FloatType, slot);
+ return loadLocal(TypeKind.FloatType, slot);
}
/**
@@ -1423,7 +1262,7 @@ default CodeBuilder fload(int slot) {
* @return this builder
*/
default CodeBuilder fmul() {
- return operatorInstruction(Opcode.FMUL);
+ return with(OperatorInstruction.of(Opcode.FMUL));
}
/**
@@ -1431,7 +1270,7 @@ default CodeBuilder fmul() {
* @return this builder
*/
default CodeBuilder fneg() {
- return operatorInstruction(Opcode.FNEG);
+ return with(OperatorInstruction.of(Opcode.FNEG));
}
/**
@@ -1439,7 +1278,7 @@ default CodeBuilder fneg() {
* @return this builder
*/
default CodeBuilder frem() {
- return operatorInstruction(Opcode.FREM);
+ return with(OperatorInstruction.of(Opcode.FREM));
}
/**
@@ -1447,7 +1286,7 @@ default CodeBuilder frem() {
* @return this builder
*/
default CodeBuilder freturn() {
- return returnInstruction(TypeKind.FloatType);
+ return return_(TypeKind.FloatType);
}
/**
@@ -1456,7 +1295,7 @@ default CodeBuilder freturn() {
* @return this builder
*/
default CodeBuilder fstore(int slot) {
- return storeInstruction(TypeKind.FloatType, slot);
+ return storeLocal(TypeKind.FloatType, slot);
}
/**
@@ -1464,7 +1303,7 @@ default CodeBuilder fstore(int slot) {
* @return this builder
*/
default CodeBuilder fsub() {
- return operatorInstruction(Opcode.FSUB);
+ return with(OperatorInstruction.of(Opcode.FSUB));
}
/**
@@ -1473,7 +1312,7 @@ default CodeBuilder fsub() {
* @return this builder
*/
default CodeBuilder getfield(FieldRefEntry ref) {
- return fieldInstruction(Opcode.GETFIELD, ref);
+ return fieldAccess(Opcode.GETFIELD, ref);
}
/**
@@ -1485,7 +1324,7 @@ default CodeBuilder getfield(FieldRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder getfield(ClassDesc owner, String name, ClassDesc type) {
- return fieldInstruction(Opcode.GETFIELD, owner, name, type);
+ return fieldAccess(Opcode.GETFIELD, owner, name, type);
}
/**
@@ -1494,7 +1333,7 @@ default CodeBuilder getfield(ClassDesc owner, String name, ClassDesc type) {
* @return this builder
*/
default CodeBuilder getstatic(FieldRefEntry ref) {
- return fieldInstruction(Opcode.GETSTATIC, ref);
+ return fieldAccess(Opcode.GETSTATIC, ref);
}
/**
@@ -1506,7 +1345,7 @@ default CodeBuilder getstatic(FieldRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder getstatic(ClassDesc owner, String name, ClassDesc type) {
- return fieldInstruction(Opcode.GETSTATIC, owner, name, type);
+ return fieldAccess(Opcode.GETSTATIC, owner, name, type);
}
/**
@@ -1515,7 +1354,7 @@ default CodeBuilder getstatic(ClassDesc owner, String name, ClassDesc type) {
* @return this builder
*/
default CodeBuilder goto_(Label target) {
- return branchInstruction(Opcode.GOTO, target);
+ return branch(Opcode.GOTO, target);
}
/**
@@ -1524,7 +1363,7 @@ default CodeBuilder goto_(Label target) {
* @return this builder
*/
default CodeBuilder goto_w(Label target) {
- return branchInstruction(Opcode.GOTO_W, target);
+ return branch(Opcode.GOTO_W, target);
}
/**
@@ -1532,7 +1371,7 @@ default CodeBuilder goto_w(Label target) {
* @return this builder
*/
default CodeBuilder i2b() {
- return convertInstruction(TypeKind.IntType, TypeKind.ByteType);
+ return with(ConvertInstruction.of(Opcode.I2B));
}
/**
@@ -1540,7 +1379,7 @@ default CodeBuilder i2b() {
* @return this builder
*/
default CodeBuilder i2c() {
- return convertInstruction(TypeKind.IntType, TypeKind.CharType);
+ return with(ConvertInstruction.of(Opcode.I2C));
}
/**
@@ -1548,7 +1387,7 @@ default CodeBuilder i2c() {
* @return this builder
*/
default CodeBuilder i2d() {
- return convertInstruction(TypeKind.IntType, TypeKind.DoubleType);
+ return with(ConvertInstruction.of(Opcode.I2D));
}
/**
@@ -1556,7 +1395,7 @@ default CodeBuilder i2d() {
* @return this builder
*/
default CodeBuilder i2f() {
- return convertInstruction(TypeKind.IntType, TypeKind.FloatType);
+ return with(ConvertInstruction.of(Opcode.I2F));
}
/**
@@ -1564,7 +1403,7 @@ default CodeBuilder i2f() {
* @return this builder
*/
default CodeBuilder i2l() {
- return convertInstruction(TypeKind.IntType, TypeKind.LongType);
+ return with(ConvertInstruction.of(Opcode.I2L));
}
/**
@@ -1572,7 +1411,7 @@ default CodeBuilder i2l() {
* @return this builder
*/
default CodeBuilder i2s() {
- return convertInstruction(TypeKind.IntType, TypeKind.ShortType);
+ return with(ConvertInstruction.of(Opcode.I2S));
}
/**
@@ -1580,7 +1419,7 @@ default CodeBuilder i2s() {
* @return this builder
*/
default CodeBuilder iadd() {
- return operatorInstruction(Opcode.IADD);
+ return with(OperatorInstruction.of(Opcode.IADD));
}
/**
@@ -1588,7 +1427,7 @@ default CodeBuilder iadd() {
* @return this builder
*/
default CodeBuilder iaload() {
- return arrayLoadInstruction(TypeKind.IntType);
+ return arrayLoad(TypeKind.IntType);
}
/**
@@ -1596,7 +1435,7 @@ default CodeBuilder iaload() {
* @return this builder
*/
default CodeBuilder iand() {
- return operatorInstruction(Opcode.IAND);
+ return with(OperatorInstruction.of(Opcode.IAND));
}
/**
@@ -1604,7 +1443,7 @@ default CodeBuilder iand() {
* @return this builder
*/
default CodeBuilder iastore() {
- return arrayStoreInstruction(TypeKind.IntType);
+ return arrayStore(TypeKind.IntType);
}
/**
@@ -1668,7 +1507,7 @@ default CodeBuilder iconst_m1() {
* @return this builder
*/
default CodeBuilder idiv() {
- return operatorInstruction(Opcode.IDIV);
+ return with(OperatorInstruction.of(Opcode.IDIV));
}
/**
@@ -1677,7 +1516,7 @@ default CodeBuilder idiv() {
* @return this builder
*/
default CodeBuilder if_acmpeq(Label target) {
- return branchInstruction(Opcode.IF_ACMPEQ, target);
+ return branch(Opcode.IF_ACMPEQ, target);
}
/**
@@ -1686,7 +1525,7 @@ default CodeBuilder if_acmpeq(Label target) {
* @return this builder
*/
default CodeBuilder if_acmpne(Label target) {
- return branchInstruction(Opcode.IF_ACMPNE, target);
+ return branch(Opcode.IF_ACMPNE, target);
}
/**
@@ -1695,7 +1534,7 @@ default CodeBuilder if_acmpne(Label target) {
* @return this builder
*/
default CodeBuilder if_icmpeq(Label target) {
- return branchInstruction(Opcode.IF_ICMPEQ, target);
+ return branch(Opcode.IF_ICMPEQ, target);
}
/**
@@ -1704,7 +1543,7 @@ default CodeBuilder if_icmpeq(Label target) {
* @return this builder
*/
default CodeBuilder if_icmpge(Label target) {
- return branchInstruction(Opcode.IF_ICMPGE, target);
+ return branch(Opcode.IF_ICMPGE, target);
}
/**
@@ -1713,7 +1552,7 @@ default CodeBuilder if_icmpge(Label target) {
* @return this builder
*/
default CodeBuilder if_icmpgt(Label target) {
- return branchInstruction(Opcode.IF_ICMPGT, target);
+ return branch(Opcode.IF_ICMPGT, target);
}
/**
@@ -1722,7 +1561,7 @@ default CodeBuilder if_icmpgt(Label target) {
* @return this builder
*/
default CodeBuilder if_icmple(Label target) {
- return branchInstruction(Opcode.IF_ICMPLE, target);
+ return branch(Opcode.IF_ICMPLE, target);
}
/**
@@ -1731,7 +1570,7 @@ default CodeBuilder if_icmple(Label target) {
* @return this builder
*/
default CodeBuilder if_icmplt(Label target) {
- return branchInstruction(Opcode.IF_ICMPLT, target);
+ return branch(Opcode.IF_ICMPLT, target);
}
/**
@@ -1740,7 +1579,7 @@ default CodeBuilder if_icmplt(Label target) {
* @return this builder
*/
default CodeBuilder if_icmpne(Label target) {
- return branchInstruction(Opcode.IF_ICMPNE, target);
+ return branch(Opcode.IF_ICMPNE, target);
}
/**
@@ -1749,7 +1588,7 @@ default CodeBuilder if_icmpne(Label target) {
* @return this builder
*/
default CodeBuilder if_nonnull(Label target) {
- return branchInstruction(Opcode.IFNONNULL, target);
+ return branch(Opcode.IFNONNULL, target);
}
/**
@@ -1758,7 +1597,7 @@ default CodeBuilder if_nonnull(Label target) {
* @return this builder
*/
default CodeBuilder if_null(Label target) {
- return branchInstruction(Opcode.IFNULL, target);
+ return branch(Opcode.IFNULL, target);
}
/**
@@ -1767,7 +1606,7 @@ default CodeBuilder if_null(Label target) {
* @return this builder
*/
default CodeBuilder ifeq(Label target) {
- return branchInstruction(Opcode.IFEQ, target);
+ return branch(Opcode.IFEQ, target);
}
/**
@@ -1776,7 +1615,7 @@ default CodeBuilder ifeq(Label target) {
* @return this builder
*/
default CodeBuilder ifge(Label target) {
- return branchInstruction(Opcode.IFGE, target);
+ return branch(Opcode.IFGE, target);
}
/**
@@ -1785,7 +1624,7 @@ default CodeBuilder ifge(Label target) {
* @return this builder
*/
default CodeBuilder ifgt(Label target) {
- return branchInstruction(Opcode.IFGT, target);
+ return branch(Opcode.IFGT, target);
}
/**
@@ -1794,7 +1633,7 @@ default CodeBuilder ifgt(Label target) {
* @return this builder
*/
default CodeBuilder ifle(Label target) {
- return branchInstruction(Opcode.IFLE, target);
+ return branch(Opcode.IFLE, target);
}
/**
@@ -1803,7 +1642,7 @@ default CodeBuilder ifle(Label target) {
* @return this builder
*/
default CodeBuilder iflt(Label target) {
- return branchInstruction(Opcode.IFLT, target);
+ return branch(Opcode.IFLT, target);
}
/**
@@ -1812,7 +1651,7 @@ default CodeBuilder iflt(Label target) {
* @return this builder
*/
default CodeBuilder ifne(Label target) {
- return branchInstruction(Opcode.IFNE, target);
+ return branch(Opcode.IFNE, target);
}
/**
@@ -1822,7 +1661,7 @@ default CodeBuilder ifne(Label target) {
* @return this builder
*/
default CodeBuilder iinc(int slot, int val) {
- return incrementInstruction(slot, val);
+ return with(IncrementInstruction.of(slot, val));
}
/**
@@ -1831,7 +1670,7 @@ default CodeBuilder iinc(int slot, int val) {
* @return this builder
*/
default CodeBuilder iload(int slot) {
- return loadInstruction(TypeKind.IntType, slot);
+ return loadLocal(TypeKind.IntType, slot);
}
/**
@@ -1839,7 +1678,7 @@ default CodeBuilder iload(int slot) {
* @return this builder
*/
default CodeBuilder imul() {
- return operatorInstruction(Opcode.IMUL);
+ return with(OperatorInstruction.of(Opcode.IMUL));
}
/**
@@ -1847,16 +1686,17 @@ default CodeBuilder imul() {
* @return this builder
*/
default CodeBuilder ineg() {
- return operatorInstruction(Opcode.INEG);
+ return with(OperatorInstruction.of(Opcode.INEG));
}
/**
* Generate an instruction to determine if an object is of the given type
* @param target the target type
* @return this builder
+ * @since 23
*/
- default CodeBuilder instanceof_(ClassEntry target) {
- return typeCheckInstruction(Opcode.INSTANCEOF, target);
+ default CodeBuilder instanceOf(ClassEntry target) {
+ return with(TypeCheckInstruction.of(Opcode.INSTANCEOF, target));
}
/**
@@ -1864,9 +1704,10 @@ default CodeBuilder instanceof_(ClassEntry target) {
* @param target the target type
* @return this builder
* @throws IllegalArgumentException if {@code target} represents a primitive type
+ * @since 23
*/
- default CodeBuilder instanceof_(ClassDesc target) {
- return typeCheckInstruction(Opcode.INSTANCEOF, constantPool().classEntry(target));
+ default CodeBuilder instanceOf(ClassDesc target) {
+ return instanceOf(constantPool().classEntry(target));
}
/**
@@ -1875,7 +1716,7 @@ default CodeBuilder instanceof_(ClassDesc target) {
* @return this builder
*/
default CodeBuilder invokedynamic(InvokeDynamicEntry ref) {
- return invokeDynamicInstruction(ref);
+ return with(InvokeDynamicInstruction.of(ref));
}
/**
@@ -1884,7 +1725,15 @@ default CodeBuilder invokedynamic(InvokeDynamicEntry ref) {
* @return this builder
*/
default CodeBuilder invokedynamic(DynamicCallSiteDesc ref) {
- return invokeDynamicInstruction(ref);
+ MethodHandleEntry bsMethod = handleDescToHandleInfo(constantPool(), (DirectMethodHandleDesc) ref.bootstrapMethod());
+ var cpArgs = ref.bootstrapArgs();
+ List bsArguments = new ArrayList<>(cpArgs.length);
+ for (var constantValue : cpArgs) {
+ bsArguments.add(BytecodeHelpers.constantEntry(constantPool(), constantValue));
+ }
+ BootstrapMethodEntry bm = constantPool().bsmEntry(bsMethod, bsArguments);
+ NameAndTypeEntry nameAndType = constantPool().nameAndTypeEntry(ref.invocationName(), ref.invocationType());
+ return invokedynamic(constantPool().invokeDynamicEntry(bm, nameAndType));
}
/**
@@ -1893,7 +1742,7 @@ default CodeBuilder invokedynamic(DynamicCallSiteDesc ref) {
* @return this builder
*/
default CodeBuilder invokeinterface(InterfaceMethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKEINTERFACE, ref);
+ return invoke(Opcode.INVOKEINTERFACE, ref);
}
/**
@@ -1905,7 +1754,7 @@ default CodeBuilder invokeinterface(InterfaceMethodRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokeinterface(ClassDesc owner, String name, MethodTypeDesc type) {
- return invokeInstruction(Opcode.INVOKEINTERFACE, constantPool().interfaceMethodRefEntry(owner, name, type));
+ return invoke(Opcode.INVOKEINTERFACE, constantPool().interfaceMethodRefEntry(owner, name, type));
}
/**
@@ -1915,7 +1764,7 @@ default CodeBuilder invokeinterface(ClassDesc owner, String name, MethodTypeDesc
* @return this builder
*/
default CodeBuilder invokespecial(InterfaceMethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKESPECIAL, ref);
+ return invoke(Opcode.INVOKESPECIAL, ref);
}
/**
@@ -1925,7 +1774,7 @@ default CodeBuilder invokespecial(InterfaceMethodRefEntry ref) {
* @return this builder
*/
default CodeBuilder invokespecial(MethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKESPECIAL, ref);
+ return invoke(Opcode.INVOKESPECIAL, ref);
}
/**
@@ -1938,7 +1787,7 @@ default CodeBuilder invokespecial(MethodRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokespecial(ClassDesc owner, String name, MethodTypeDesc type) {
- return invokeInstruction(Opcode.INVOKESPECIAL, owner, name, type, false);
+ return invoke(Opcode.INVOKESPECIAL, owner, name, type, false);
}
/**
@@ -1952,7 +1801,7 @@ default CodeBuilder invokespecial(ClassDesc owner, String name, MethodTypeDesc t
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokespecial(ClassDesc owner, String name, MethodTypeDesc type, boolean isInterface) {
- return invokeInstruction(Opcode.INVOKESPECIAL, owner, name, type, isInterface);
+ return invoke(Opcode.INVOKESPECIAL, owner, name, type, isInterface);
}
/**
@@ -1961,7 +1810,7 @@ default CodeBuilder invokespecial(ClassDesc owner, String name, MethodTypeDesc t
* @return this builder
*/
default CodeBuilder invokestatic(InterfaceMethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKESTATIC, ref);
+ return invoke(Opcode.INVOKESTATIC, ref);
}
/**
@@ -1970,7 +1819,7 @@ default CodeBuilder invokestatic(InterfaceMethodRefEntry ref) {
* @return this builder
*/
default CodeBuilder invokestatic(MethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKESTATIC, ref);
+ return invoke(Opcode.INVOKESTATIC, ref);
}
/**
@@ -1982,7 +1831,7 @@ default CodeBuilder invokestatic(MethodRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokestatic(ClassDesc owner, String name, MethodTypeDesc type) {
- return invokeInstruction(Opcode.INVOKESTATIC, owner, name, type, false);
+ return invoke(Opcode.INVOKESTATIC, owner, name, type, false);
}
/**
@@ -1995,7 +1844,7 @@ default CodeBuilder invokestatic(ClassDesc owner, String name, MethodTypeDesc ty
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokestatic(ClassDesc owner, String name, MethodTypeDesc type, boolean isInterface) {
- return invokeInstruction(Opcode.INVOKESTATIC, owner, name, type, isInterface);
+ return invoke(Opcode.INVOKESTATIC, owner, name, type, isInterface);
}
/**
@@ -2004,7 +1853,7 @@ default CodeBuilder invokestatic(ClassDesc owner, String name, MethodTypeDesc ty
* @return this builder
*/
default CodeBuilder invokevirtual(MethodRefEntry ref) {
- return invokeInstruction(Opcode.INVOKEVIRTUAL, ref);
+ return invoke(Opcode.INVOKEVIRTUAL, ref);
}
/**
@@ -2016,7 +1865,7 @@ default CodeBuilder invokevirtual(MethodRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder invokevirtual(ClassDesc owner, String name, MethodTypeDesc type) {
- return invokeInstruction(Opcode.INVOKEVIRTUAL, owner, name, type, false);
+ return invoke(Opcode.INVOKEVIRTUAL, owner, name, type, false);
}
/**
@@ -2024,7 +1873,7 @@ default CodeBuilder invokevirtual(ClassDesc owner, String name, MethodTypeDesc t
* @return this builder
*/
default CodeBuilder ior() {
- return operatorInstruction(Opcode.IOR);
+ return with(OperatorInstruction.of(Opcode.IOR));
}
/**
@@ -2032,7 +1881,7 @@ default CodeBuilder ior() {
* @return this builder
*/
default CodeBuilder irem() {
- return operatorInstruction(Opcode.IREM);
+ return with(OperatorInstruction.of(Opcode.IREM));
}
/**
@@ -2040,7 +1889,7 @@ default CodeBuilder irem() {
* @return this builder
*/
default CodeBuilder ireturn() {
- return returnInstruction(TypeKind.IntType);
+ return return_(TypeKind.IntType);
}
/**
@@ -2048,7 +1897,7 @@ default CodeBuilder ireturn() {
* @return this builder
*/
default CodeBuilder ishl() {
- return operatorInstruction(Opcode.ISHL);
+ return with(OperatorInstruction.of(Opcode.ISHL));
}
/**
@@ -2056,7 +1905,7 @@ default CodeBuilder ishl() {
* @return this builder
*/
default CodeBuilder ishr() {
- return operatorInstruction(Opcode.ISHR);
+ return with(OperatorInstruction.of(Opcode.ISHR));
}
/**
@@ -2065,7 +1914,7 @@ default CodeBuilder ishr() {
* @return this builder
*/
default CodeBuilder istore(int slot) {
- return storeInstruction(TypeKind.IntType, slot);
+ return storeLocal(TypeKind.IntType, slot);
}
/**
@@ -2073,7 +1922,7 @@ default CodeBuilder istore(int slot) {
* @return this builder
*/
default CodeBuilder isub() {
- return operatorInstruction(Opcode.ISUB);
+ return with(OperatorInstruction.of(Opcode.ISUB));
}
/**
@@ -2081,7 +1930,7 @@ default CodeBuilder isub() {
* @return this builder
*/
default CodeBuilder iushr() {
- return operatorInstruction(Opcode.IUSHR);
+ return with(OperatorInstruction.of(Opcode.IUSHR));
}
/**
@@ -2089,7 +1938,7 @@ default CodeBuilder iushr() {
* @return this builder
*/
default CodeBuilder ixor() {
- return operatorInstruction(Opcode.IXOR);
+ return with(OperatorInstruction.of(Opcode.IXOR));
}
/**
@@ -2099,7 +1948,7 @@ default CodeBuilder ixor() {
* @return this builder
*/
default CodeBuilder lookupswitch(Label defaultTarget, List cases) {
- return lookupSwitchInstruction(defaultTarget, cases);
+ return with(LookupSwitchInstruction.of(defaultTarget, cases));
}
/**
@@ -2107,7 +1956,7 @@ default CodeBuilder lookupswitch(Label defaultTarget, List cases) {
* @return this builder
*/
default CodeBuilder l2d() {
- return convertInstruction(TypeKind.LongType, TypeKind.DoubleType);
+ return with(ConvertInstruction.of(Opcode.L2D));
}
/**
@@ -2115,7 +1964,7 @@ default CodeBuilder l2d() {
* @return this builder
*/
default CodeBuilder l2f() {
- return convertInstruction(TypeKind.LongType, TypeKind.FloatType);
+ return with(ConvertInstruction.of(Opcode.L2F));
}
/**
@@ -2123,7 +1972,7 @@ default CodeBuilder l2f() {
* @return this builder
*/
default CodeBuilder l2i() {
- return convertInstruction(TypeKind.LongType, TypeKind.IntType);
+ return with(ConvertInstruction.of(Opcode.L2I));
}
/**
@@ -2131,7 +1980,7 @@ default CodeBuilder l2i() {
* @return this builder
*/
default CodeBuilder ladd() {
- return operatorInstruction(Opcode.LADD);
+ return with(OperatorInstruction.of(Opcode.LADD));
}
/**
@@ -2139,7 +1988,7 @@ default CodeBuilder ladd() {
* @return this builder
*/
default CodeBuilder laload() {
- return arrayLoadInstruction(TypeKind.LongType);
+ return arrayLoad(TypeKind.LongType);
}
/**
@@ -2147,7 +1996,7 @@ default CodeBuilder laload() {
* @return this builder
*/
default CodeBuilder land() {
- return operatorInstruction(Opcode.LAND);
+ return with(OperatorInstruction.of(Opcode.LAND));
}
/**
@@ -2155,7 +2004,7 @@ default CodeBuilder land() {
* @return this builder
*/
default CodeBuilder lastore() {
- return arrayStoreInstruction(TypeKind.LongType);
+ return arrayStore(TypeKind.LongType);
}
/**
@@ -2163,7 +2012,7 @@ default CodeBuilder lastore() {
* @return this builder
*/
default CodeBuilder lcmp() {
- return operatorInstruction(Opcode.LCMP);
+ return with(OperatorInstruction.of(Opcode.LCMP));
}
/**
@@ -2208,7 +2057,7 @@ default CodeBuilder ldc(LoadableConstantEntry entry) {
* @return this builder
*/
default CodeBuilder ldiv() {
- return operatorInstruction(Opcode.LDIV);
+ return with(OperatorInstruction.of(Opcode.LDIV));
}
/**
@@ -2217,7 +2066,7 @@ default CodeBuilder ldiv() {
* @return this builder
*/
default CodeBuilder lload(int slot) {
- return loadInstruction(TypeKind.LongType, slot);
+ return loadLocal(TypeKind.LongType, slot);
}
/**
@@ -2225,7 +2074,7 @@ default CodeBuilder lload(int slot) {
* @return this builder
*/
default CodeBuilder lmul() {
- return operatorInstruction(Opcode.LMUL);
+ return with(OperatorInstruction.of(Opcode.LMUL));
}
/**
@@ -2233,7 +2082,7 @@ default CodeBuilder lmul() {
* @return this builder
*/
default CodeBuilder lneg() {
- return operatorInstruction(Opcode.LNEG);
+ return with(OperatorInstruction.of(Opcode.LNEG));
}
/**
@@ -2241,7 +2090,7 @@ default CodeBuilder lneg() {
* @return this builder
*/
default CodeBuilder lor() {
- return operatorInstruction(Opcode.LOR);
+ return with(OperatorInstruction.of(Opcode.LOR));
}
/**
@@ -2249,7 +2098,7 @@ default CodeBuilder lor() {
* @return this builder
*/
default CodeBuilder lrem() {
- return operatorInstruction(Opcode.LREM);
+ return with(OperatorInstruction.of(Opcode.LREM));
}
/**
@@ -2257,7 +2106,7 @@ default CodeBuilder lrem() {
* @return this builder
*/
default CodeBuilder lreturn() {
- return returnInstruction(TypeKind.LongType);
+ return return_(TypeKind.LongType);
}
/**
@@ -2265,7 +2114,7 @@ default CodeBuilder lreturn() {
* @return this builder
*/
default CodeBuilder lshl() {
- return operatorInstruction(Opcode.LSHL);
+ return with(OperatorInstruction.of(Opcode.LSHL));
}
/**
@@ -2273,7 +2122,7 @@ default CodeBuilder lshl() {
* @return this builder
*/
default CodeBuilder lshr() {
- return operatorInstruction(Opcode.LSHR);
+ return with(OperatorInstruction.of(Opcode.LSHR));
}
/**
@@ -2282,7 +2131,7 @@ default CodeBuilder lshr() {
* @return this builder
*/
default CodeBuilder lstore(int slot) {
- return storeInstruction(TypeKind.LongType, slot);
+ return storeLocal(TypeKind.LongType, slot);
}
/**
@@ -2290,7 +2139,7 @@ default CodeBuilder lstore(int slot) {
* @return this builder
*/
default CodeBuilder lsub() {
- return operatorInstruction(Opcode.LSUB);
+ return with(OperatorInstruction.of(Opcode.LSUB));
}
/**
@@ -2298,7 +2147,7 @@ default CodeBuilder lsub() {
* @return this builder
*/
default CodeBuilder lushr() {
- return operatorInstruction(Opcode.LUSHR);
+ return with(OperatorInstruction.of(Opcode.LUSHR));
}
/**
@@ -2306,7 +2155,7 @@ default CodeBuilder lushr() {
* @return this builder
*/
default CodeBuilder lxor() {
- return operatorInstruction(Opcode.LXOR);
+ return with(OperatorInstruction.of(Opcode.LXOR));
}
/**
@@ -2314,7 +2163,7 @@ default CodeBuilder lxor() {
* @return this builder
*/
default CodeBuilder monitorenter() {
- return monitorInstruction(Opcode.MONITORENTER);
+ return with(MonitorInstruction.of(Opcode.MONITORENTER));
}
/**
@@ -2322,7 +2171,7 @@ default CodeBuilder monitorenter() {
* @return this builder
*/
default CodeBuilder monitorexit() {
- return monitorInstruction(Opcode.MONITOREXIT);
+ return with(MonitorInstruction.of(Opcode.MONITOREXIT));
}
/**
@@ -2332,7 +2181,7 @@ default CodeBuilder monitorexit() {
* @return this builder
*/
default CodeBuilder multianewarray(ClassEntry array, int dims) {
- return newMultidimensionalArrayInstruction(dims, array);
+ return with(NewMultiArrayInstruction.of(array, dims));
}
/**
@@ -2343,7 +2192,7 @@ default CodeBuilder multianewarray(ClassEntry array, int dims) {
* @throws IllegalArgumentException if {@code array} represents a primitive type
*/
default CodeBuilder multianewarray(ClassDesc array, int dims) {
- return newMultidimensionalArrayInstruction(dims, constantPool().classEntry(array));
+ return multianewarray(constantPool().classEntry(array), dims);
}
/**
@@ -2352,7 +2201,7 @@ default CodeBuilder multianewarray(ClassDesc array, int dims) {
* @return this builder
*/
default CodeBuilder new_(ClassEntry clazz) {
- return newObjectInstruction(clazz);
+ return with(NewObjectInstruction.of(clazz));
}
/**
@@ -2362,7 +2211,7 @@ default CodeBuilder new_(ClassEntry clazz) {
* @throws IllegalArgumentException if {@code clazz} represents a primitive type
*/
default CodeBuilder new_(ClassDesc clazz) {
- return newObjectInstruction(constantPool().classEntry(clazz));
+ return new_(constantPool().classEntry(clazz));
}
/**
@@ -2371,7 +2220,7 @@ default CodeBuilder new_(ClassDesc clazz) {
* @return this builder
*/
default CodeBuilder newarray(TypeKind typeKind) {
- return newPrimitiveArrayInstruction(typeKind);
+ return with(NewPrimitiveArrayInstruction.of(typeKind));
}
/**
@@ -2379,7 +2228,7 @@ default CodeBuilder newarray(TypeKind typeKind) {
* @return this builder
*/
default CodeBuilder pop() {
- return stackInstruction(Opcode.POP);
+ return with(StackInstruction.of(Opcode.POP));
}
/**
@@ -2387,7 +2236,7 @@ default CodeBuilder pop() {
* @return this builder
*/
default CodeBuilder pop2() {
- return stackInstruction(Opcode.POP2);
+ return with(StackInstruction.of(Opcode.POP2));
}
/**
@@ -2396,7 +2245,7 @@ default CodeBuilder pop2() {
* @return this builder
*/
default CodeBuilder putfield(FieldRefEntry ref) {
- return fieldInstruction(Opcode.PUTFIELD, ref);
+ return fieldAccess(Opcode.PUTFIELD, ref);
}
/**
@@ -2408,7 +2257,7 @@ default CodeBuilder putfield(FieldRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder putfield(ClassDesc owner, String name, ClassDesc type) {
- return fieldInstruction(Opcode.PUTFIELD, owner, name, type);
+ return fieldAccess(Opcode.PUTFIELD, owner, name, type);
}
/**
@@ -2417,7 +2266,7 @@ default CodeBuilder putfield(ClassDesc owner, String name, ClassDesc type) {
* @return this builder
*/
default CodeBuilder putstatic(FieldRefEntry ref) {
- return fieldInstruction(Opcode.PUTSTATIC, ref);
+ return fieldAccess(Opcode.PUTSTATIC, ref);
}
/**
@@ -2429,7 +2278,7 @@ default CodeBuilder putstatic(FieldRefEntry ref) {
* @throws IllegalArgumentException if {@code owner} represents a primitive type
*/
default CodeBuilder putstatic(ClassDesc owner, String name, ClassDesc type) {
- return fieldInstruction(Opcode.PUTSTATIC, owner, name, type);
+ return fieldAccess(Opcode.PUTSTATIC, owner, name, type);
}
/**
@@ -2437,7 +2286,7 @@ default CodeBuilder putstatic(ClassDesc owner, String name, ClassDesc type) {
* @return this builder
*/
default CodeBuilder return_() {
- return returnInstruction(TypeKind.VoidType);
+ return return_(TypeKind.VoidType);
}
/**
@@ -2445,7 +2294,7 @@ default CodeBuilder return_() {
* @return this builder
*/
default CodeBuilder saload() {
- return arrayLoadInstruction(TypeKind.ShortType);
+ return arrayLoad(TypeKind.ShortType);
}
/**
@@ -2453,7 +2302,7 @@ default CodeBuilder saload() {
* @return this builder
*/
default CodeBuilder sastore() {
- return arrayStoreInstruction(TypeKind.ShortType);
+ return arrayStore(TypeKind.ShortType);
}
/**
@@ -2462,7 +2311,7 @@ default CodeBuilder sastore() {
* @return this builder
*/
default CodeBuilder sipush(int s) {
- return constantInstruction(Opcode.SIPUSH, s);
+ return loadConstant(Opcode.SIPUSH, s);
}
/**
@@ -2470,7 +2319,7 @@ default CodeBuilder sipush(int s) {
* @return this builder
*/
default CodeBuilder swap() {
- return stackInstruction(Opcode.SWAP);
+ return with(StackInstruction.of(Opcode.SWAP));
}
/**
@@ -2482,7 +2331,7 @@ default CodeBuilder swap() {
* @return this builder
*/
default CodeBuilder tableswitch(int low, int high, Label defaultTarget, List cases) {
- return tableSwitchInstruction(low, high, defaultTarget, cases);
+ return with(TableSwitchInstruction.of(low, high, defaultTarget, cases));
}
/**
@@ -2499,6 +2348,6 @@ default CodeBuilder tableswitch(Label defaultTarget, List cases) {
if (i < low) low = i;
if (i > high) high = i;
}
- return tableSwitchInstruction(low, high, defaultTarget, cases);
+ return tableswitch(low, high, defaultTarget, cases);
}
}
diff --git a/src/java.base/share/classes/java/lang/classfile/package-info.java b/src/java.base/share/classes/java/lang/classfile/package-info.java
index e7e75d5abc3..0c4919067d5 100644
--- a/src/java.base/share/classes/java/lang/classfile/package-info.java
+++ b/src/java.base/share/classes/java/lang/classfile/package-info.java
@@ -228,7 +228,7 @@
* instruction invoking {@code println} could have been generated with {@link
* java.lang.classfile.CodeBuilder#invokevirtual(java.lang.constant.ClassDesc,
* java.lang.String, java.lang.constant.MethodTypeDesc) CodeBuilder.invokevirtual}, {@link
- * java.lang.classfile.CodeBuilder#invokeInstruction(java.lang.classfile.Opcode,
+ * java.lang.classfile.CodeBuilder#invoke(java.lang.classfile.Opcode,
* java.lang.constant.ClassDesc, java.lang.String, java.lang.constant.MethodTypeDesc,
* boolean) CodeBuilder.invokeInstruction}, or {@link
* java.lang.classfile.CodeBuilder#with(java.lang.classfile.ClassFileElement)
diff --git a/src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java b/src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java
index 3776c6f66e9..5073e108465 100644
--- a/src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java
+++ b/src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java
@@ -213,7 +213,7 @@ void fooToBarTransform() {
if (e instanceof InvokeInstruction i
&& i.owner().asInternalName().equals("Foo")
&& i.opcode() == Opcode.INVOKESTATIC)
- b.invokeInstruction(i.opcode(), CD_Bar, i.name().stringValue(), i.typeSymbol(), i.isInterface());
+ b.invoke(i.opcode(), CD_Bar, i.name().stringValue(), i.typeSymbol(), i.isInterface());
else b.with(e);
};
// @end
@@ -327,7 +327,7 @@ void fooToBarUnrolled(ClassModel classModel) {
for (CodeElement e : xm) {
if (e instanceof InvokeInstruction i && i.owner().asInternalName().equals("Foo")
&& i.opcode() == Opcode.INVOKESTATIC)
- codeBuilder.invokeInstruction(i.opcode(), CD_Bar,
+ codeBuilder.invoke(i.opcode(), CD_Bar,
i.name().stringValue(), i.typeSymbol(), i.isInterface());
else codeBuilder.with(e);
}});
diff --git a/src/java.base/share/classes/java/lang/constant/ClassDesc.java b/src/java.base/share/classes/java/lang/constant/ClassDesc.java
index f645fbd1141..89be851dbf5 100644
--- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java
+++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@ public sealed interface ClassDesc
extends ConstantDesc,
TypeDescriptor.OfField
permits PrimitiveClassDescImpl,
- ClassDescImpl {
+ ReferenceClassDescImpl {
/**
* Returns a {@linkplain ClassDesc} for a class or interface type,
@@ -158,20 +158,11 @@ static ClassDesc of(String packageName, String className) {
* @see ClassDesc#ofInternalName(String)
*/
static ClassDesc ofDescriptor(String descriptor) {
- requireNonNull(descriptor);
- if (descriptor.isEmpty()) {
- throw new IllegalArgumentException(
- "not a valid reference type descriptor: " + descriptor);
- }
- int depth = ConstantUtils.arrayDepth(descriptor);
- if (depth > ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
- throw new IllegalArgumentException(
- "Cannot create an array type descriptor with more than " +
- ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS + " dimensions");
- }
+ // implicit null-check
return (descriptor.length() == 1)
- ? new PrimitiveClassDescImpl(descriptor)
- : new ClassDescImpl(descriptor);
+ ? Wrapper.forPrimitiveType(descriptor.charAt(0)).classDescriptor()
+ // will throw IAE on descriptor.length == 0 or if array dimensions too long
+ : new ReferenceClassDescImpl(descriptor);
}
/**
@@ -279,7 +270,7 @@ default ClassDesc nested(String firstNestedName, String... moreNestedNames) {
* @return whether this {@linkplain ClassDesc} describes an array type
*/
default boolean isArray() {
- return descriptorString().startsWith("[");
+ return descriptorString().charAt(0) == '[';
}
/**
@@ -297,7 +288,7 @@ default boolean isPrimitive() {
* @return whether this {@linkplain ClassDesc} describes a class or interface type
*/
default boolean isClassOrInterface() {
- return descriptorString().startsWith("L");
+ return descriptorString().charAt(0) == 'L';
}
/**
diff --git a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java
index 82f56b7cbd4..a67a16643c3 100644
--- a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java
+++ b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,125 +64,125 @@ private ConstantDescs() { }
// Don't change the order of these declarations!
/** {@link ClassDesc} representing {@link Object} */
- public static final ClassDesc CD_Object = ClassDesc.of("java.lang.Object");
+ public static final ClassDesc CD_Object = new ReferenceClassDescImpl("Ljava/lang/Object;");
/** {@link ClassDesc} representing {@link String} */
- public static final ClassDesc CD_String = ClassDesc.of("java.lang.String");
+ public static final ClassDesc CD_String = new ReferenceClassDescImpl("Ljava/lang/String;");
/** {@link ClassDesc} representing {@link Class} */
- public static final ClassDesc CD_Class = ClassDesc.of("java.lang.Class");
+ public static final ClassDesc CD_Class = new ReferenceClassDescImpl("Ljava/lang/Class;");
/** {@link ClassDesc} representing {@link Number} */
- public static final ClassDesc CD_Number = ClassDesc.of("java.lang.Number");
+ public static final ClassDesc CD_Number = new ReferenceClassDescImpl("Ljava/lang/Number;");
/** {@link ClassDesc} representing {@link Integer} */
- public static final ClassDesc CD_Integer = ClassDesc.of("java.lang.Integer");
+ public static final ClassDesc CD_Integer = new ReferenceClassDescImpl("Ljava/lang/Integer;");
/** {@link ClassDesc} representing {@link Long} */
- public static final ClassDesc CD_Long = ClassDesc.of("java.lang.Long");
+ public static final ClassDesc CD_Long = new ReferenceClassDescImpl("Ljava/lang/Long;");
/** {@link ClassDesc} representing {@link Float} */
- public static final ClassDesc CD_Float = ClassDesc.of("java.lang.Float");
+ public static final ClassDesc CD_Float = new ReferenceClassDescImpl("Ljava/lang/Float;");
/** {@link ClassDesc} representing {@link Double} */
- public static final ClassDesc CD_Double = ClassDesc.of("java.lang.Double");
+ public static final ClassDesc CD_Double = new ReferenceClassDescImpl("Ljava/lang/Double;");
/** {@link ClassDesc} representing {@link Short} */
- public static final ClassDesc CD_Short = ClassDesc.of("java.lang.Short");
+ public static final ClassDesc CD_Short = new ReferenceClassDescImpl("Ljava/lang/Short;");
/** {@link ClassDesc} representing {@link Byte} */
- public static final ClassDesc CD_Byte = ClassDesc.of("java.lang.Byte");
+ public static final ClassDesc CD_Byte = new ReferenceClassDescImpl("Ljava/lang/Byte;");
/** {@link ClassDesc} representing {@link Character} */
- public static final ClassDesc CD_Character = ClassDesc.of("java.lang.Character");
+ public static final ClassDesc CD_Character = new ReferenceClassDescImpl("Ljava/lang/Character;");
/** {@link ClassDesc} representing {@link Boolean} */
- public static final ClassDesc CD_Boolean = ClassDesc.of("java.lang.Boolean");
+ public static final ClassDesc CD_Boolean = new ReferenceClassDescImpl("Ljava/lang/Boolean;");
/** {@link ClassDesc} representing {@link Void} */
- public static final ClassDesc CD_Void = ClassDesc.of("java.lang.Void");
+ public static final ClassDesc CD_Void = new ReferenceClassDescImpl("Ljava/lang/Void;");
/** {@link ClassDesc} representing {@link Throwable} */
- public static final ClassDesc CD_Throwable = ClassDesc.of("java.lang.Throwable");
+ public static final ClassDesc CD_Throwable = new ReferenceClassDescImpl("Ljava/lang/Throwable;");
/** {@link ClassDesc} representing {@link Exception} */
- public static final ClassDesc CD_Exception = ClassDesc.of("java.lang.Exception");
+ public static final ClassDesc CD_Exception = new ReferenceClassDescImpl("Ljava/lang/Exception;");
/** {@link ClassDesc} representing {@link Enum} */
- public static final ClassDesc CD_Enum = ClassDesc.of("java.lang.Enum");
+ public static final ClassDesc CD_Enum = new ReferenceClassDescImpl("Ljava/lang/Enum;");
/** {@link ClassDesc} representing {@link VarHandle} */
- public static final ClassDesc CD_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle");
+ public static final ClassDesc CD_VarHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle;");
/** {@link ClassDesc} representing {@link MethodHandles} */
- public static final ClassDesc CD_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles");
+ public static final ClassDesc CD_MethodHandles = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles;");
/** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
- public static final ClassDesc CD_MethodHandles_Lookup = CD_MethodHandles.nested("Lookup");
+ public static final ClassDesc CD_MethodHandles_Lookup = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles$Lookup;");
/** {@link ClassDesc} representing {@link MethodHandle} */
- public static final ClassDesc CD_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle");
+ public static final ClassDesc CD_MethodHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandle;");
/** {@link ClassDesc} representing {@link MethodType} */
- public static final ClassDesc CD_MethodType = ClassDesc.of("java.lang.invoke.MethodType");
+ public static final ClassDesc CD_MethodType = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodType;");
/** {@link ClassDesc} representing {@link CallSite} */
- public static final ClassDesc CD_CallSite = ClassDesc.of("java.lang.invoke.CallSite");
+ public static final ClassDesc CD_CallSite = new ReferenceClassDescImpl("Ljava/lang/invoke/CallSite;");
/** {@link ClassDesc} representing {@link Collection} */
- public static final ClassDesc CD_Collection = ClassDesc.of("java.util.Collection");
+ public static final ClassDesc CD_Collection = new ReferenceClassDescImpl("Ljava/util/Collection;");
/** {@link ClassDesc} representing {@link List} */
- public static final ClassDesc CD_List = ClassDesc.of("java.util.List");
+ public static final ClassDesc CD_List = new ReferenceClassDescImpl("Ljava/util/List;");
/** {@link ClassDesc} representing {@link Set} */
- public static final ClassDesc CD_Set = ClassDesc.of("java.util.Set");
+ public static final ClassDesc CD_Set = new ReferenceClassDescImpl("Ljava/util/Set;");
/** {@link ClassDesc} representing {@link Map} */
- public static final ClassDesc CD_Map = ClassDesc.of("java.util.Map");
+ public static final ClassDesc CD_Map = new ReferenceClassDescImpl("Ljava/util/Map;");
/** {@link ClassDesc} representing {@link ConstantDesc} */
- public static final ClassDesc CD_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc");
+ public static final ClassDesc CD_ConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ConstantDesc;");
/** {@link ClassDesc} representing {@link ClassDesc} */
- public static final ClassDesc CD_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc");
+ public static final ClassDesc CD_ClassDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ClassDesc;");
/** {@link ClassDesc} representing {@link EnumDesc} */
- public static final ClassDesc CD_EnumDesc = CD_Enum.nested("EnumDesc");
+ public static final ClassDesc CD_EnumDesc = new ReferenceClassDescImpl("Ljava/lang/Enum$EnumDesc;");
/** {@link ClassDesc} representing {@link MethodTypeDesc} */
- public static final ClassDesc CD_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc");
+ public static final ClassDesc CD_MethodTypeDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodTypeDesc;");
/** {@link ClassDesc} representing {@link MethodHandleDesc} */
- public static final ClassDesc CD_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc");
+ public static final ClassDesc CD_MethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodHandleDesc;");
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc} */
- public static final ClassDesc CD_DirectMethodHandleDesc = ClassDesc.of("java.lang.constant.DirectMethodHandleDesc");
+ public static final ClassDesc CD_DirectMethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc;");
/** {@link ClassDesc} representing {@link VarHandleDesc} */
- public static final ClassDesc CD_VarHandleDesc = CD_VarHandle.nested("VarHandleDesc");
+ public static final ClassDesc CD_VarHandleDesc = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle$VarHandleDesc;");
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */
- public static final ClassDesc CD_MethodHandleDesc_Kind = CD_DirectMethodHandleDesc.nested("Kind");
+ public static final ClassDesc CD_MethodHandleDesc_Kind = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc$Kind;");
/** {@link ClassDesc} representing {@link DynamicConstantDesc} */
- public static final ClassDesc CD_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc");
+ public static final ClassDesc CD_DynamicConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicConstantDesc;");
/** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
- public static final ClassDesc CD_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc");
+ public static final ClassDesc CD_DynamicCallSiteDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicCallSiteDesc;");
/** {@link ClassDesc} representing {@link ConstantBootstraps} */
- public static final ClassDesc CD_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
+ public static final ClassDesc CD_ConstantBootstraps = new ReferenceClassDescImpl("Ljava/lang/invoke/ConstantBootstraps;");
private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
- ConstantDescs.CD_MethodHandles_Lookup,
- ConstantDescs.CD_String,
- ConstantDescs.CD_MethodType};
+ CD_MethodHandles_Lookup,
+ CD_String,
+ CD_MethodType};
private static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
- ConstantDescs.CD_MethodHandles_Lookup,
- ConstantDescs.CD_String,
- ConstantDescs.CD_Class};
+ CD_MethodHandles_Lookup,
+ CD_String,
+ CD_Class};
/** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class) ConstantBootstraps.primitiveClass} */
public static final DirectMethodHandleDesc BSM_PRIMITIVE_CLASS
@@ -236,31 +236,31 @@ private ConstantDescs() { }
CD_Object, CD_Object);
/** {@link ClassDesc} representing the primitive type {@code int} */
- public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I");
+ public static final ClassDesc CD_int = new PrimitiveClassDescImpl("I");
/** {@link ClassDesc} representing the primitive type {@code long} */
- public static final ClassDesc CD_long = ClassDesc.ofDescriptor("J");
+ public static final ClassDesc CD_long = new PrimitiveClassDescImpl("J");
/** {@link ClassDesc} representing the primitive type {@code float} */
- public static final ClassDesc CD_float = ClassDesc.ofDescriptor("F");
+ public static final ClassDesc CD_float = new PrimitiveClassDescImpl("F");
/** {@link ClassDesc} representing the primitive type {@code double} */
- public static final ClassDesc CD_double = ClassDesc.ofDescriptor("D");
+ public static final ClassDesc CD_double = new PrimitiveClassDescImpl("D");
/** {@link ClassDesc} representing the primitive type {@code short} */
- public static final ClassDesc CD_short = ClassDesc.ofDescriptor("S");
+ public static final ClassDesc CD_short = new PrimitiveClassDescImpl("S");
/** {@link ClassDesc} representing the primitive type {@code byte} */
- public static final ClassDesc CD_byte = ClassDesc.ofDescriptor("B");
+ public static final ClassDesc CD_byte = new PrimitiveClassDescImpl("B");
/** {@link ClassDesc} representing the primitive type {@code char} */
- public static final ClassDesc CD_char = ClassDesc.ofDescriptor("C");
+ public static final ClassDesc CD_char = new PrimitiveClassDescImpl("C");
/** {@link ClassDesc} representing the primitive type {@code boolean} */
- public static final ClassDesc CD_boolean = ClassDesc.ofDescriptor("Z");
+ public static final ClassDesc CD_boolean = new PrimitiveClassDescImpl("Z");
/** {@link ClassDesc} representing the primitive type {@code void} */
- public static final ClassDesc CD_void = ClassDesc.ofDescriptor("V");
+ public static final ClassDesc CD_void = new PrimitiveClassDescImpl("V");
/**
* {@link MethodHandleDesc} representing {@link MethodHandles#classData(Lookup, String, Class) MethodHandles.classData}
diff --git a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java
index 37bb75cf3d8..d8a1ccd543b 100644
--- a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java
+++ b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
*/
package java.lang.constant;
+import sun.invoke.util.Wrapper;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -144,7 +146,6 @@ public static String validateModuleName(String name) {
* @throws IllegalArgumentException if the member name is invalid
*/
public static String validateMemberName(String name, boolean method) {
- requireNonNull(name);
if (name.length() == 0)
throw new IllegalArgumentException("zero-length member name");
for (int i=0; i parseMethodDescriptor(String descriptor) {
+ static List parseMethodDescriptor(String descriptor) {
int cur = 0, end = descriptor.length();
- ArrayList ptypes = new ArrayList<>();
+ ArrayList ptypes = new ArrayList<>();
+ ptypes.add(null); // placeholder for return type
if (cur >= end || descriptor.charAt(cur) != '(')
throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
@@ -207,7 +209,7 @@ static List parseMethodDescriptor(String descriptor) {
int len = skipOverFieldSignature(descriptor, cur, end, false);
if (len == 0)
throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
- ptypes.add(descriptor.substring(cur, cur + len));
+ ptypes.add(resolveClassDesc(descriptor, cur, len));
cur += len;
}
if (cur >= end)
@@ -217,10 +219,17 @@ static List parseMethodDescriptor(String descriptor) {
int rLen = skipOverFieldSignature(descriptor, cur, end, true);
if (rLen == 0 || cur + rLen != end)
throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
- ptypes.add(0, descriptor.substring(cur, cur + rLen));
+ ptypes.set(0, resolveClassDesc(descriptor, cur, rLen));
return ptypes;
}
+ private static ClassDesc resolveClassDesc(String descriptor, int start, int len) {
+ if (len == 1) {
+ return Wrapper.forPrimitiveType(descriptor.charAt(start)).classDescriptor();
+ }
+ return ClassDesc.ofDescriptor(descriptor.substring(start, start + len));
+ }
+
private static final char JVM_SIGNATURE_ARRAY = '[';
private static final char JVM_SIGNATURE_BYTE = 'B';
private static final char JVM_SIGNATURE_CHAR = 'C';
diff --git a/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java b/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java
index 77f61d83133..47aa3dc36d2 100644
--- a/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java
+++ b/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java
@@ -67,8 +67,8 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
name = "";
requireNonNull(kind);
- validateClassOrInterface(requireNonNull(owner));
- validateMemberName(requireNonNull(name), true);
+ validateClassOrInterface(owner);
+ validateMemberName(name, true);
requireNonNull(type);
switch (kind) {
diff --git a/src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java b/src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java
index bf6ae2670b1..180841cd798 100644
--- a/src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java
+++ b/src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java
@@ -87,12 +87,9 @@ protected DynamicConstantDesc(DirectMethodHandleDesc bootstrapMethod,
ClassDesc constantType,
ConstantDesc... bootstrapArgs) {
this.bootstrapMethod = requireNonNull(bootstrapMethod);
- this.constantName = validateMemberName(requireNonNull(constantName), true);
+ this.constantName = validateMemberName(constantName, true);
this.constantType = requireNonNull(constantType);
- this.bootstrapArgs = requireNonNull(bootstrapArgs).clone();
-
- if (constantName.length() == 0)
- throw new IllegalArgumentException("Illegal invocation name: " + constantName);
+ this.bootstrapArgs = bootstrapArgs.length == 0 ? EMPTY_CONSTANTDESC : bootstrapArgs.clone();
}
/**
diff --git a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java
index c50cf7c58f0..7ee0995439a 100644
--- a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
-import java.util.StringJoiner;
import static java.util.Objects.requireNonNull;
@@ -55,8 +54,8 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
* @param validatedArgTypes {@link ClassDesc}s describing the trusted and validated parameter types
*/
private MethodTypeDescImpl(ClassDesc returnType, ClassDesc[] validatedArgTypes) {
- this.returnType = requireNonNull(returnType);
- this.argTypes = requireNonNull(validatedArgTypes);
+ this.returnType = returnType;
+ this.argTypes = validatedArgTypes;
}
/**
@@ -67,12 +66,12 @@ private MethodTypeDescImpl(ClassDesc returnType, ClassDesc[] validatedArgTypes)
* @param trustedArgTypes {@link ClassDesc}s describing the trusted parameter types
*/
static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArgTypes) {
- Objects.requireNonNull(returnType);
+ requireNonNull(returnType);
if (trustedArgTypes.length == 0) // implicit null check
return new MethodTypeDescImpl(returnType, ConstantUtils.EMPTY_CLASSDESC);
for (ClassDesc cd : trustedArgTypes)
- if (cd.isPrimitive() && cd.descriptorString().charAt(0) == 'V') // implicit null check
+ if (cd.descriptorString().charAt(0) == 'V') // implicit null check
throw new IllegalArgumentException("Void parameters not permitted");
return new MethodTypeDescImpl(returnType, trustedArgTypes);
@@ -88,21 +87,19 @@ static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArg
* @jvms 4.3.3 Method Descriptors
*/
static MethodTypeDescImpl ofDescriptor(String descriptor) {
- requireNonNull(descriptor);
-
- List types = ConstantUtils.parseMethodDescriptor(descriptor);
-
- int paramCount = types.size() - 1;
- var paramTypes = paramCount > 0 ? new ClassDesc[paramCount] : ConstantUtils.EMPTY_CLASSDESC;
- for (int i = 0; i < paramCount; i++) {
- paramTypes[i] = ClassDesc.ofDescriptor(types.get(i + 1));
- }
-
- MethodTypeDescImpl result = ofTrusted(ClassDesc.ofDescriptor(types.getFirst()), paramTypes);
+ // Implicit null-check of descriptor
+ List ptypes = ConstantUtils.parseMethodDescriptor(descriptor);
+ int args = ptypes.size() - 1;
+ ClassDesc[] paramTypes = args > 0
+ ? ptypes.subList(1, args + 1).toArray(ConstantUtils.EMPTY_CLASSDESC)
+ : ConstantUtils.EMPTY_CLASSDESC;
+
+ MethodTypeDescImpl result = ofTrusted(ptypes.get(0), paramTypes);
result.cachedDescriptorString = descriptor;
return result;
}
+
@Override
public ClassDesc returnType() {
return returnType;
@@ -130,7 +127,7 @@ public ClassDesc[] parameterArray() {
@Override
public MethodTypeDesc changeReturnType(ClassDesc returnType) {
- return new MethodTypeDescImpl(returnType, argTypes);
+ return new MethodTypeDescImpl(requireNonNull(returnType), argTypes);
}
@Override
@@ -146,8 +143,12 @@ public MethodTypeDesc dropParameterTypes(int start, int end) {
Objects.checkFromToIndex(start, end, argTypes.length);
ClassDesc[] newArgs = new ClassDesc[argTypes.length - (end - start)];
- System.arraycopy(argTypes, 0, newArgs, 0, start);
- System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
+ if (start > 0) {
+ System.arraycopy(argTypes, 0, newArgs, 0, start);
+ }
+ if (end < argTypes.length) {
+ System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
+ }
return ofTrusted(returnType, newArgs);
}
@@ -157,10 +158,13 @@ public MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes) {
throw new IndexOutOfBoundsException(pos);
ClassDesc[] newArgs = new ClassDesc[argTypes.length + paramTypes.length];
- System.arraycopy(argTypes, 0, newArgs, 0, pos);
+ if (pos > 0) {
+ System.arraycopy(argTypes, 0, newArgs, 0, pos);
+ }
System.arraycopy(paramTypes, 0, newArgs, pos, paramTypes.length);
- System.arraycopy(argTypes, pos, newArgs, pos+paramTypes.length, argTypes.length - pos);
-
+ if (pos < argTypes.length) {
+ System.arraycopy(argTypes, pos, newArgs, pos + paramTypes.length, argTypes.length - pos);
+ }
return ofTrusted(returnType, newArgs);
}
@@ -170,11 +174,17 @@ public String descriptorString() {
if (desc != null)
return desc;
- var sj = new StringJoiner("", "(", ")" + returnType().descriptorString());
- for (int i = 0; i < parameterCount(); i++) {
- sj.add(parameterType(i).descriptorString());
+ int len = 2 + returnType.descriptorString().length();
+ for (ClassDesc argType : argTypes) {
+ len += argType.descriptorString().length();
+ }
+ StringBuilder sb = new StringBuilder(len).append('(');
+ for (ClassDesc argType : argTypes) {
+ sb.append(argType.descriptorString());
}
- return cachedDescriptorString = sj.toString();
+ desc = sb.append(')').append(returnType.descriptorString()).toString();
+ cachedDescriptorString = desc;
+ return desc;
}
@Override
diff --git a/src/java.base/share/classes/java/lang/constant/ClassDescImpl.java b/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java
similarity index 90%
rename from src/java.base/share/classes/java/lang/constant/ClassDescImpl.java
rename to src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java
index 4e2b0d6791e..5e2aaa98442 100644
--- a/src/java.base/share/classes/java/lang/constant/ClassDescImpl.java
+++ b/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java
@@ -31,10 +31,10 @@
/**
* A nominal descriptor for a class,
- * interface, or array type. A {@linkplain ClassDescImpl} corresponds to a
+ * interface, or array type. A {@linkplain ReferenceClassDescImpl} corresponds to a
* {@code Constant_Class_info} entry in the constant pool of a classfile.
*/
-final class ClassDescImpl implements ClassDesc {
+final class ReferenceClassDescImpl implements ClassDesc {
private final String descriptor;
/**
@@ -46,11 +46,10 @@ final class ClassDescImpl implements ClassDesc {
* field descriptor string, or does not describe a class or interface type
* @jvms 4.3.2 Field Descriptors
*/
- ClassDescImpl(String descriptor) {
- requireNonNull(descriptor);
- int len = ConstantUtils.skipOverFieldSignature(descriptor, 0, descriptor.length(), false);
- if (len == 0 || len == 1
- || len != descriptor.length())
+ ReferenceClassDescImpl(String descriptor) {
+ int dLen = descriptor.length();
+ int len = ConstantUtils.skipOverFieldSignature(descriptor, 0, dLen, false);
+ if (len <= 1 || len != dLen)
throw new IllegalArgumentException(String.format("not a valid reference type descriptor: %s", descriptor));
this.descriptor = descriptor;
}
@@ -88,8 +87,8 @@ private boolean isPrimitiveArray() {
}
/**
- * Returns {@code true} if this {@linkplain ClassDescImpl} is
- * equal to another {@linkplain ClassDescImpl}. Equality is
+ * Returns {@code true} if this {@linkplain ReferenceClassDescImpl} is
+ * equal to another {@linkplain ReferenceClassDescImpl}. Equality is
* determined by the two class descriptors having equal class descriptor
* strings.
*
diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java
index fb325ef1d44..545a83984f8 100644
--- a/src/java.base/share/classes/java/lang/foreign/Linker.java
+++ b/src/java.base/share/classes/java/lang/foreign/Linker.java
@@ -88,7 +88,7 @@
* {@snippet lang = java:
* Linker linker = Linker.nativeLinker();
* MethodHandle strlen = linker.downcallHandle(
- * linker.defaultLookup().find("strlen").orElseThrow(),
+ * linker.defaultLookup().findOrThrow("strlen"),
* FunctionDescriptor.of(JAVA_LONG, ADDRESS)
* );
* }
@@ -306,7 +306,7 @@
* {@snippet lang = java:
* Linker linker = Linker.nativeLinker();
* MethodHandle qsort = linker.downcallHandle(
- * linker.defaultLookup().find("qsort").orElseThrow(),
+ * linker.defaultLookup().findOrThrow("qsort"),
* FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG, JAVA_LONG, ADDRESS)
* );
* }
@@ -397,12 +397,12 @@
* Linker linker = Linker.nativeLinker();
*
* MethodHandle malloc = linker.downcallHandle(
- * linker.defaultLookup().find("malloc").orElseThrow(),
+ * linker.defaultLookup().findOrThrow("malloc"),
* FunctionDescriptor.of(ADDRESS, JAVA_LONG)
* );
*
* MethodHandle free = linker.downcallHandle(
- * linker.defaultLookup().find("free").orElseThrow(),
+ * linker.defaultLookup().findOrThrow("free"),
* FunctionDescriptor.ofVoid(ADDRESS)
* );
* }
@@ -530,7 +530,7 @@
* {@snippet lang = java:
* Linker linker = Linker.nativeLinker();
* MethodHandle printf = linker.downcallHandle(
- * linker.defaultLookup().find("printf").orElseThrow(),
+ * linker.defaultLookup().findOrThrow("printf"),
* FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT),
* Linker.Option.firstVariadicArg(1) // first int is variadic
* );
diff --git a/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java b/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java
index 9bfc7964322..3bc416b9c62 100644
--- a/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java
+++ b/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java
@@ -39,6 +39,7 @@
import java.lang.invoke.MethodHandles;
import java.nio.file.FileSystems;
import java.nio.file.Path;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
@@ -79,7 +80,7 @@
* {@snippet lang = java:
* try (Arena arena = Arena.ofConfined()) {
* SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena); // libGL.so loaded here
- * MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
+ * MemorySegment glGetString = libGL.findOrThrow("glGetString");
* ...
* } // libGL.so unloaded here
*}
@@ -93,7 +94,7 @@
* System.loadLibrary("GL"); // libGL.so loaded here
* ...
* SymbolLookup libGL = SymbolLookup.loaderLookup();
- * MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
+ * MemorySegment glGetString = libGL.findOrThrow("glGetString");
* }
*
* This symbol lookup, which is known as a loader lookup , is dynamic with
@@ -130,7 +131,7 @@
* {@snippet lang = java:
* Linker nativeLinker = Linker.nativeLinker();
* SymbolLookup stdlib = nativeLinker.defaultLookup();
- * MemorySegment malloc = stdlib.find("malloc").orElseThrow();
+ * MemorySegment malloc = stdlib.findOrThrow("malloc");
*}
*
* @since 22
@@ -144,9 +145,40 @@ public interface SymbolLookup {
* @param name the symbol name
* @return a zero-length memory segment whose address indicates the address of
* the symbol, if found
+ * @see #findOrThrow(String)
*/
Optional find(String name);
+ /**
+ * Returns the address of the symbol with the given name or throws an exception.
+ *
+ * This is equivalent to the following code, but is more efficient:
+ * to:
+ * {@snippet lang= java :
+ * String name = ...
+ * MemorySegment address = lookup.find(name)
+ * .orElseThrow(() -> new NoSuchElementException("Symbol not found: " + name));
+ * }
+ *
+ * @param name the symbol name
+ * @return a zero-length memory segment whose address indicates the address of
+ * the symbol
+ * @throws NoSuchElementException if no symbol address can be found for the
+ * given name
+ * @see #find(String)
+ *
+ * @since 23
+ */
+ default MemorySegment findOrThrow(String name) {
+ Objects.requireNonNull(name);
+ Optional address = find(name);
+ // Avoid lambda capturing
+ if (address.isPresent()) {
+ return address.get();
+ }
+ throw new NoSuchElementException("Symbol not found: " + name);
+ }
+
/**
* {@return a composed symbol lookup that returns the result of finding the symbol
* with this lookup if found, otherwise returns the result of finding
diff --git a/src/java.base/share/classes/java/lang/foreign/package-info.java b/src/java.base/share/classes/java/lang/foreign/package-info.java
index b2a6a5f4474..6594826e405 100644
--- a/src/java.base/share/classes/java/lang/foreign/package-info.java
+++ b/src/java.base/share/classes/java/lang/foreign/package-info.java
@@ -100,7 +100,7 @@
* Linker linker = Linker.nativeLinker();
* SymbolLookup stdlib = linker.defaultLookup();
* MethodHandle strlen = linker.downcallHandle(
- * stdlib.find("strlen").orElseThrow(),
+ * stdlib.findOrThrow("strlen"),
* FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
* );
*
@@ -111,7 +111,7 @@
*}
*
* Here, we obtain a {@linkplain java.lang.foreign.Linker#nativeLinker() native linker}
- * and we use it to {@linkplain java.lang.foreign.SymbolLookup#find(java.lang.String) look up}
+ * and we use it to {@linkplain java.lang.foreign.SymbolLookup#findOrThrow(java.lang.String) look up}
* the {@code strlen} function in the standard C library; a downcall method handle
* targeting said function is subsequently
* {@linkplain java.lang.foreign.Linker#downcallHandle(FunctionDescriptor, Linker.Option...) obtained}.
diff --git a/src/java.base/share/classes/java/lang/foreign/snippet-files/Snippets.java b/src/java.base/share/classes/java/lang/foreign/snippet-files/Snippets.java
index 95b9cce7541..f305586ac61 100644
--- a/src/java.base/share/classes/java/lang/foreign/snippet-files/Snippets.java
+++ b/src/java.base/share/classes/java/lang/foreign/snippet-files/Snippets.java
@@ -163,7 +163,7 @@ static class LinkerSnippets {
void downcall() throws Throwable {
Linker linker = Linker.nativeLinker();
MethodHandle strlen = linker.downcallHandle(
- linker.defaultLookup().find("strlen").orElseThrow(),
+ linker.defaultLookup().findOrThrow("strlen"),
FunctionDescriptor.of(JAVA_LONG, ADDRESS)
);
@@ -177,7 +177,7 @@ void downcall() throws Throwable {
void qsort() throws Throwable {
Linker linker = Linker.nativeLinker();
MethodHandle qsort = linker.downcallHandle(
- linker.defaultLookup().find("qsort").orElseThrow(),
+ linker.defaultLookup().findOrThrow("qsort"),
FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG, JAVA_LONG, ADDRESS)
);
@@ -208,12 +208,12 @@ void returnPointer() throws Throwable {
Linker linker = Linker.nativeLinker();
MethodHandle malloc = linker.downcallHandle(
- linker.defaultLookup().find("malloc").orElseThrow(),
+ linker.defaultLookup().findOrThrow("malloc"),
FunctionDescriptor.of(ADDRESS, JAVA_LONG)
);
MethodHandle free = linker.downcallHandle(
- linker.defaultLookup().find("free").orElseThrow(),
+ linker.defaultLookup().findOrThrow("free"),
FunctionDescriptor.ofVoid(ADDRESS)
);
@@ -282,7 +282,7 @@ void variadicFunc() throws Throwable {
Linker linker = Linker.nativeLinker();
MethodHandle printf = linker.downcallHandle(
- linker.defaultLookup().find("printf").orElseThrow(),
+ linker.defaultLookup().findOrThrow("printf"),
FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT),
Linker.Option.firstVariadicArg(1) // first int is variadic
);
@@ -568,7 +568,7 @@ void header() throws Throwable {
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle strlen = linker.downcallHandle(
- stdlib.find("strlen").orElseThrow(),
+ stdlib.findOrThrow("strlen"),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
);
@@ -626,14 +626,14 @@ static class SymbolLookupSnippets {
void header() {
try (Arena arena = Arena.ofConfined()) {
SymbolLookup libGL = libraryLookup("libGL.so", arena); // libGL.so loaded here
- MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
+ MemorySegment glGetString = libGL.findOrThrow("glGetString");
// ...
} // libGL.so unloaded here
System.loadLibrary("GL"); // libGL.so loaded here
// ...
SymbolLookup libGL = loaderLookup();
- MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
+ MemorySegment glGetString = libGL.findOrThrow("glGetString");
Arena arena = Arena.ofAuto();
@@ -647,7 +647,7 @@ void header() {
Linker nativeLinker = Linker.nativeLinker();
SymbolLookup stdlib = nativeLinker.defaultLookup();
- MemorySegment malloc = stdlib.find("malloc").orElseThrow();
+ MemorySegment malloc = stdlib.findOrThrow("malloc");
}
}
diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
index 93b9cf299db..79845dd9570 100644
--- a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
@@ -575,7 +575,7 @@ boolean nameRefsAreLegal() {
return true;
}
- /** Invoke this form on the given arguments. */
+ // /** Invoke this form on the given arguments. */
// final Object invoke(Object... args) throws Throwable {
// // NYI: fit this into the fast path?
// return interpretWithArguments(args);
@@ -927,9 +927,9 @@ private boolean forceInterpretation() {
return invocationCounter == -1;
}
+ /** Interpretively invoke this form on the given arguments. */
@Hidden
@DontInline
- /** Interpretively invoke this form on the given arguments. */
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
return interpretWithArgumentsTracing(argumentValues);
@@ -944,9 +944,9 @@ Object interpretWithArguments(Object... argumentValues) throws Throwable {
return rv;
}
+ /** Evaluate a single Name within this form, applying its function to its arguments. */
@Hidden
@DontInline
- /** Evaluate a single Name within this form, applying its function to its arguments. */
Object interpretName(Name name, Object[] values) throws Throwable {
if (TRACE_INTERPRETER)
traceInterpreter("| interpretName", name.debugString(), (Object[]) null);
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
index adef2a586ea..0a099bc8c08 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
@@ -383,7 +383,7 @@ private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, Cl
//
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
- cob.constantInstruction(ifaceDesc);
+ cob.loadConstant(ifaceDesc);
cob.putstatic(proxyDesc, TYPE_NAME, CD_Class);
cob.return_();
});
@@ -407,7 +407,7 @@ private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, Cl
// this.m = callerBoundTarget.asType(xxType);
cob.aload(0);
cob.aload(3);
- cob.constantInstruction(mi.desc);
+ cob.loadConstant(mi.desc);
cob.invokevirtual(CD_MethodHandle, "asType", MTD_MethodHandle_MethodType);
cob.putfield(proxyDesc, mi.fieldName, CD_MethodHandle);
}
@@ -424,12 +424,12 @@ private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, Cl
// check lookupClass
cob.aload(0);
cob.invokevirtual(CD_MethodHandles_Lookup, "lookupClass", MTD_Class);
- cob.constantInstruction(proxyDesc);
+ cob.loadConstant(proxyDesc);
cob.if_acmpne(failLabel);
// check original access
cob.aload(0);
cob.invokevirtual(CD_MethodHandles_Lookup, "lookupModes", MTD_int);
- cob.constantInstruction(Lookup.ORIGINAL);
+ cob.loadConstant(Lookup.ORIGINAL);
cob.iand();
cob.ifeq(failLabel);
// success
@@ -453,11 +453,11 @@ private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, Cl
bcb.aload(0);
bcb.getfield(proxyDesc, mi.fieldName, CD_MethodHandle);
for (int j = 0; j < mi.desc.parameterCount(); j++) {
- bcb.loadInstruction(TypeKind.from(mi.desc.parameterType(j)),
+ bcb.loadLocal(TypeKind.from(mi.desc.parameterType(j)),
bcb.parameterSlot(j));
}
bcb.invokevirtual(CD_MethodHandle, "invokeExact", mi.desc);
- bcb.returnInstruction(TypeKind.from(mi.desc.returnType()));
+ bcb.return_(TypeKind.from(mi.desc.returnType()));
}, ctb -> ctb
// catch (Error | RuntimeException | Declared ex) { throw ex; }
.catchingMulti(mi.thrown, CodeBuilder::athrow)
diff --git a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
index b918b756332..3499fd83525 100644
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,16 +27,25 @@
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
-import jdk.internal.javac.PreviewFeature;
+import jdk.internal.misc.VM;
+import jdk.internal.util.ClassFileDumper;
import jdk.internal.vm.annotation.Stable;
import sun.invoke.util.Wrapper;
+import java.lang.classfile.ClassBuilder;
+import java.lang.classfile.ClassFile;
+import java.lang.classfile.CodeBuilder;
+import java.lang.classfile.TypeKind;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.MethodHandles.Lookup;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.lang.reflect.AccessFlag;
import java.util.Objects;
+import java.util.Set;
+import java.util.function.Consumer;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOption.STRONG;
import static java.lang.invoke.MethodType.methodType;
/**
@@ -98,6 +107,13 @@
*/
public final class StringConcatFactory {
+ private static final int HIGH_ARITY_THRESHOLD;
+
+ static {
+ String highArity = VM.getSavedProperty("java.lang.invoke.StringConcat.highArityThreshold");
+ HIGH_ARITY_THRESHOLD = highArity != null ? Integer.parseInt(highArity) : 20;
+ }
+
/**
* Tag used to demarcate an ordinary argument.
*/
@@ -354,9 +370,14 @@ public static CallSite makeConcatWithConstants(MethodHandles.Lookup lookup,
}
try {
- return new ConstantCallSite(
- generateMHInlineCopy(concatType, constantStrings)
- .viewAsType(concatType, true));
+ if (concatType.parameterCount() <= HIGH_ARITY_THRESHOLD) {
+ return new ConstantCallSite(
+ generateMHInlineCopy(concatType, constantStrings)
+ .viewAsType(concatType, true));
+ } else {
+ return new ConstantCallSite(
+ SimpleStringBuilderStrategy.generate(lookup, concatType, constantStrings));
+ }
} catch (Error e) {
// Pass through any error
throw e;
@@ -1032,4 +1053,140 @@ private StringConcatFactory() {
// no instantiation
}
+ /**
+ * Bytecode StringBuilder strategy.
+ *
+ * This strategy emits StringBuilder chains as similar as possible
+ * to what javac would. No exact sizing of parameters or estimates.
+ */
+ private static final class SimpleStringBuilderStrategy {
+ static final String METHOD_NAME = "concat";
+ static final ClassDesc STRING_BUILDER = ClassDesc.ofDescriptor("Ljava/lang/StringBuilder;");
+ static final ClassFileDumper DUMPER =
+ ClassFileDumper.getInstance("java.lang.invoke.StringConcatFactory.dump", "stringConcatClasses");
+ static final MethodTypeDesc APPEND_BOOLEAN_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_boolean);
+ static final MethodTypeDesc APPEND_CHAR_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_char);
+ static final MethodTypeDesc APPEND_DOUBLE_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_double);
+ static final MethodTypeDesc APPEND_FLOAT_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_float);
+ static final MethodTypeDesc APPEND_INT_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_int);
+ static final MethodTypeDesc APPEND_LONG_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_long);
+ static final MethodTypeDesc APPEND_OBJECT_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_Object);
+ static final MethodTypeDesc APPEND_STRING_TYPE = MethodTypeDesc.of(STRING_BUILDER, ConstantDescs.CD_String);
+ static final MethodTypeDesc INT_CONSTRUCTOR_TYPE = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_int);
+ static final MethodTypeDesc TO_STRING_TYPE = MethodTypeDesc.of(ConstantDescs.CD_String);
+
+ /**
+ * Ensure a capacity in the initial StringBuilder to accommodate all
+ * constants plus this factor times the number of arguments.
+ */
+ static final int ARGUMENT_SIZE_FACTOR = 4;
+
+ static final Set SET_OF_STRONG = Set.of(STRONG);
+
+ private SimpleStringBuilderStrategy() {
+ // no instantiation
+ }
+
+ private static MethodHandle generate(Lookup lookup, MethodType args, String[] constants) throws Exception {
+ String className = getClassName(lookup.lookupClass());
+
+ byte[] classBytes = ClassFile.of().build(ClassDesc.of(className),
+ new Consumer() {
+ @Override
+ public void accept(ClassBuilder clb) {
+ clb.withFlags(AccessFlag.FINAL, AccessFlag.SUPER, AccessFlag.SYNTHETIC)
+ .withMethodBody(METHOD_NAME,
+ MethodTypeDesc.ofDescriptor(args.toMethodDescriptorString()),
+ ClassFile.ACC_FINAL | ClassFile.ACC_PRIVATE | ClassFile.ACC_STATIC,
+ generateMethod(constants, args));
+ }});
+ try {
+ Lookup hiddenLookup = lookup.makeHiddenClassDefiner(className, classBytes, SET_OF_STRONG, DUMPER)
+ .defineClassAsLookup(true);
+ Class> innerClass = hiddenLookup.lookupClass();
+ return hiddenLookup.findStatic(innerClass, METHOD_NAME, args);
+ } catch (Exception e) {
+ throw new StringConcatException("Exception while spinning the class", e);
+ }
+ }
+
+ private static Consumer generateMethod(String[] constants, MethodType args) {
+ return new Consumer() {
+ @Override
+ public void accept(CodeBuilder cb) {
+ cb.new_(STRING_BUILDER);
+ cb.dup();
+
+ int len = 0;
+ for (String constant : constants) {
+ if (constant != null) {
+ len += constant.length();
+ }
+ }
+ len += args.parameterCount() * ARGUMENT_SIZE_FACTOR;
+ cb.loadConstant(len);
+ cb.invokespecial(STRING_BUILDER, "", INT_CONSTRUCTOR_TYPE);
+
+ // At this point, we have a blank StringBuilder on stack, fill it in with .append calls.
+ {
+ int off = 0;
+ for (int c = 0; c < args.parameterCount(); c++) {
+ if (constants[c] != null) {
+ cb.ldc(constants[c]);
+ cb.invokevirtual(STRING_BUILDER, "append", APPEND_STRING_TYPE);
+ }
+ Class> cl = args.parameterType(c);
+ TypeKind kind = TypeKind.from(cl);
+ cb.loadLocal(kind, off);
+ off += kind.slotSize();
+ MethodTypeDesc desc = getSBAppendDesc(cl);
+ cb.invokevirtual(STRING_BUILDER, "append", desc);
+ }
+ if (constants[constants.length - 1] != null) {
+ cb.ldc(constants[constants.length - 1]);
+ cb.invokevirtual(STRING_BUILDER, "append", APPEND_STRING_TYPE);
+ }
+ }
+
+ cb.invokevirtual(STRING_BUILDER, "toString", TO_STRING_TYPE);
+ cb.areturn();
+ }
+ };
+ }
+
+ /**
+ * The generated class is in the same package as the host class as
+ * it's the implementation of the string concatenation for the host
+ * class.
+ */
+ private static String getClassName(Class> hostClass) {
+ String name = hostClass.isHidden() ? hostClass.getName().replace('/', '_')
+ : hostClass.getName();
+ return name + "$$StringConcat";
+ }
+
+ private static MethodTypeDesc getSBAppendDesc(Class> cl) {
+ if (cl.isPrimitive()) {
+ if (cl == Integer.TYPE || cl == Byte.TYPE || cl == Short.TYPE) {
+ return APPEND_INT_TYPE;
+ } else if (cl == Boolean.TYPE) {
+ return APPEND_BOOLEAN_TYPE;
+ } else if (cl == Character.TYPE) {
+ return APPEND_CHAR_TYPE;
+ } else if (cl == Double.TYPE) {
+ return APPEND_DOUBLE_TYPE;
+ } else if (cl == Float.TYPE) {
+ return APPEND_FLOAT_TYPE;
+ } else if (cl == Long.TYPE) {
+ return APPEND_LONG_TYPE;
+ } else {
+ throw new IllegalStateException("Unhandled primitive StringBuilder.append: " + cl);
+ }
+ } else if (cl == String.class) {
+ return APPEND_STRING_TYPE;
+ } else {
+ return APPEND_OBJECT_TYPE;
+ }
+ }
+ }
}
diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java
index 04974eca743..d4ff88867aa 100644
--- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java
+++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java
@@ -696,7 +696,7 @@ private static void generateLookupAccessor(ClassBuilder clb) {
.block(blockBuilder -> blockBuilder
.aload(cob.parameterSlot(0))
.invokevirtual(CD_MethodHandles_Lookup, "lookupClass", MTD_Class)
- .constantInstruction(Opcode.LDC, CD_Proxy)
+ .ldc(CD_Proxy)
.if_acmpne(blockBuilder.breakLabel())
.aload(cob.parameterSlot(0))
.invokevirtual(CD_MethodHandles_Lookup, "hasFullPrivilegeAccess", MTD_boolean)
@@ -770,11 +770,11 @@ private void generateMethod(ClassBuilder clb, ClassEntry className) {
if (parameterTypes.length > 0) {
// Create an array and fill with the parameters converting primitives to wrappers
- cob.constantInstruction(parameterTypes.length)
+ cob.loadConstant(parameterTypes.length)
.anewarray(CE_Object);
for (int i = 0; i < parameterTypes.length; i++) {
cob.dup()
- .constantInstruction(i);
+ .loadConstant(i);
codeWrapArgument(cob, parameterTypes[i], cob.parameterSlot(i));
cob.aastore();
}
@@ -818,7 +818,7 @@ private void generateMethod(ClassBuilder clb, ClassEntry className) {
*/
private void codeWrapArgument(CodeBuilder cob, Class> type, int slot) {
if (type.isPrimitive()) {
- cob.loadInstruction(TypeKind.from(type).asLoadable(), slot);
+ cob.loadLocal(TypeKind.from(type).asLoadable(), slot);
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
cob.invokestatic(prim.wrapperMethodRef);
} else {
@@ -837,7 +837,7 @@ private void codeUnwrapReturnValue(CodeBuilder cob, Class> type) {
cob.checkcast(prim.wrapperClass)
.invokevirtual(prim.unwrapMethodRef)
- .returnInstruction(TypeKind.from(type).asLoadable());
+ .return_(TypeKind.from(type).asLoadable());
} else {
cob.checkcast(toClassDesc(type))
.areturn();
@@ -854,13 +854,13 @@ private void codeFieldInitialization(CodeBuilder cob, ClassEntry className) {
codeClassForName(cob, fromClass);
cob.ldc(method.getName())
- .constantInstruction(parameterTypes.length)
+ .loadConstant(parameterTypes.length)
.anewarray(CE_Class);
// Construct an array with the parameter types mapping primitives to Wrapper types
for (int i = 0; i < parameterTypes.length; i++) {
cob.dup()
- .constantInstruction(i);
+ .loadConstant(i);
if (parameterTypes[i].isPrimitive()) {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(parameterTypes[i]);
cob.getstatic(prim.typeFieldRef);
diff --git a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
index a8e690e3e0f..75d0d415d08 100644
--- a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
+++ b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
@@ -414,7 +414,7 @@ private static Consumer generateTypeSwitchSkeleton(Class> selecto
cb.ireturn();
cb.labelBinding(nonNullLabel);
if (labelConstants.length == 0) {
- cb.constantInstruction(0)
+ cb.loadConstant(0)
.ireturn();
return;
}
@@ -454,7 +454,7 @@ record Element(Label target, Label next, Object caseLabel) { }
// Object o = ...
// o instanceof Wrapped(float)
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(Wrapper.forBasicType(classLabel)
+ cb.instanceOf(Wrapper.forBasicType(classLabel)
.wrapperType()
.describeConstable()
.orElseThrow());
@@ -464,7 +464,7 @@ record Element(Label target, Label next, Object caseLabel) { }
// o instanceof float
Label notNumber = cb.newLabel();
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(ConstantDescs.CD_Number);
+ cb.instanceOf(ConstantDescs.CD_Number);
if (selectorType == long.class || selectorType == float.class || selectorType == double.class ||
selectorType == Long.class || selectorType == Float.class || selectorType == Double.class) {
cb.ifeq(next);
@@ -493,7 +493,7 @@ record Element(Label target, Label next, Object caseLabel) { }
cb.goto_(compare);
cb.labelBinding(notNumber);
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(ConstantDescs.CD_Character);
+ cb.instanceOf(ConstantDescs.CD_Character);
cb.ifeq(next);
cb.aload(SELECTOR_OBJ);
cb.checkcast(ConstantDescs.CD_Character);
@@ -514,11 +514,11 @@ record Element(Label target, Label next, Object caseLabel) { }
Optional classLabelConstableOpt = classLabel.describeConstable();
if (classLabelConstableOpt.isPresent()) {
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(classLabelConstableOpt.orElseThrow());
+ cb.instanceOf(classLabelConstableOpt.orElseThrow());
cb.ifeq(next);
} else {
cb.aload(EXTRA_CLASS_LABELS);
- cb.constantInstruction(extraClassLabels.size());
+ cb.loadConstant(extraClassLabels.size());
cb.invokeinterface(ConstantDescs.CD_List,
"get",
MethodTypeDesc.of(ConstantDescs.CD_Object,
@@ -537,7 +537,7 @@ record Element(Label target, Label next, Object caseLabel) { }
int enumIdx = enumDescs.size();
enumDescs.add(enumLabel);
cb.aload(ENUM_CACHE);
- cb.constantInstruction(enumIdx);
+ cb.loadConstant(enumIdx);
cb.invokestatic(ConstantDescs.CD_Integer,
"valueOf",
MethodTypeDesc.of(ConstantDescs.CD_Integer,
@@ -561,7 +561,7 @@ record Element(Label target, Label next, Object caseLabel) { }
Label compare = cb.newLabel();
Label notNumber = cb.newLabel();
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(ConstantDescs.CD_Number);
+ cb.instanceOf(ConstantDescs.CD_Number);
cb.ifeq(notNumber);
cb.aload(SELECTOR_OBJ);
cb.checkcast(ConstantDescs.CD_Number);
@@ -571,7 +571,7 @@ record Element(Label target, Label next, Object caseLabel) { }
cb.goto_(compare);
cb.labelBinding(notNumber);
cb.aload(SELECTOR_OBJ);
- cb.instanceof_(ConstantDescs.CD_Character);
+ cb.instanceOf(ConstantDescs.CD_Character);
cb.ifeq(next);
cb.aload(SELECTOR_OBJ);
cb.checkcast(ConstantDescs.CD_Character);
@@ -587,9 +587,9 @@ record Element(Label target, Label next, Object caseLabel) { }
element.caseLabel() instanceof Double ||
element.caseLabel() instanceof Boolean)) {
if (element.caseLabel() instanceof Boolean c) {
- cb.constantInstruction(c ? 1 : 0);
+ cb.loadConstant(c ? 1 : 0);
} else {
- cb.constantInstruction((ConstantDesc) element.caseLabel());
+ cb.loadConstant((ConstantDesc) element.caseLabel());
}
cb.invokestatic(element.caseLabel().getClass().describeConstable().orElseThrow(),
"valueOf",
@@ -605,11 +605,11 @@ record Element(Label target, Label next, Object caseLabel) { }
throw new InternalError("Unsupported label type: " +
element.caseLabel().getClass());
}
- cb.constantInstruction(idx);
+ cb.loadConstant(idx);
cb.ireturn();
}
cb.labelBinding(dflt);
- cb.constantInstruction(cases.size());
+ cb.loadConstant(cases.size());
cb.ireturn();
};
}
diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java
index 8d12c6de0a7..a972faafb45 100644
--- a/src/java.base/share/classes/java/math/BigInteger.java
+++ b/src/java.base/share/classes/java/math/BigInteger.java
@@ -4843,7 +4843,7 @@ private static int[] makePositive(int[] a) {
0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x39aa400
};
- /**
+ /*
* These routines provide access to the two's complement representation
* of BigIntegers.
*/
diff --git a/src/java.base/share/classes/java/math/MutableBigInteger.java b/src/java.base/share/classes/java/math/MutableBigInteger.java
index 76e48d00cf1..eca42ee25b1 100644
--- a/src/java.base/share/classes/java/math/MutableBigInteger.java
+++ b/src/java.base/share/classes/java/math/MutableBigInteger.java
@@ -25,6 +25,10 @@
package java.math;
+import static java.math.BigDecimal.INFLATED;
+import static java.math.BigInteger.LONG_MASK;
+import java.util.Arrays;
+
/**
* A class used to represent multiprecision integers that makes efficient
* use of allocated space by allowing a number to occupy only part of
@@ -42,10 +46,6 @@
* @since 1.3
*/
-import static java.math.BigDecimal.INFLATED;
-import static java.math.BigInteger.LONG_MASK;
-import java.util.Arrays;
-
class MutableBigInteger {
/**
* Holds the magnitude of this MutableBigInteger in big endian order.
diff --git a/src/java.base/share/classes/java/net/HttpURLConnection.java b/src/java.base/share/classes/java/net/HttpURLConnection.java
index b501fa25e45..b405fb10a16 100644
--- a/src/java.base/share/classes/java/net/HttpURLConnection.java
+++ b/src/java.base/share/classes/java/net/HttpURLConnection.java
@@ -675,7 +675,7 @@ public InputStream getErrorStream() {
return null;
}
- /**
+ /*
* The response codes for HTTP, as of version 1.1.
*/
diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java
index 8c0c658cb96..b73141dd7cc 100644
--- a/src/java.base/share/classes/java/net/InetAddress.java
+++ b/src/java.base/share/classes/java/net/InetAddress.java
@@ -1238,11 +1238,11 @@ public Stream lookupByName(String host, LookupPolicy policy)
Objects.requireNonNull(policy);
validate(host);
InetAddress[] addrs;
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
addrs = impl.lookupAllHostAddr(host, policy);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
return Arrays.stream(addrs);
}
@@ -1252,11 +1252,11 @@ public String lookupByAddress(byte[] addr) throws UnknownHostException {
if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
throw new IllegalArgumentException("Invalid address length");
}
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
return impl.getHostByAddr(addr);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
}
}
diff --git a/src/java.base/share/classes/java/nio/MappedMemoryUtils.java b/src/java.base/share/classes/java/nio/MappedMemoryUtils.java
index 5113d2730c2..cf6f953d8b2 100644
--- a/src/java.base/share/classes/java/nio/MappedMemoryUtils.java
+++ b/src/java.base/share/classes/java/nio/MappedMemoryUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,13 +98,13 @@ static void force(FileDescriptor fd, long address, boolean isSync, long index, l
long offset = mappingOffset(address, index);
long mappingAddress = mappingAddress(address, offset, index);
long mappingLength = mappingLength(offset, length);
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
force0(fd, mappingAddress, mappingLength);
} catch (IOException cause) {
throw new UncheckedIOException(cause);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
}
}
diff --git a/src/java.base/share/classes/java/text/CompactNumberFormat.java b/src/java.base/share/classes/java/text/CompactNumberFormat.java
index a477d9c2fd8..115a21ee662 100644
--- a/src/java.base/share/classes/java/text/CompactNumberFormat.java
+++ b/src/java.base/share/classes/java/text/CompactNumberFormat.java
@@ -47,80 +47,113 @@
/**
*
* {@code CompactNumberFormat} is a concrete subclass of {@code NumberFormat}
- * that formats a decimal number in its compact form.
- *
- * The compact number formatting is designed for the environment where the space
- * is limited, and the formatted string can be displayed in that limited space.
- * It is defined by LDML's specification for
+ * that formats a decimal number in a localized compact form.
+ * Compact number formatting is designed for an environment with limited space.
+ * For example, displaying the formatted number {@code 7M} instead of {@code
+ * 7,000,000.00} in the {@link java.util.Locale#US US locale}. The {@code
+ * CompactNumberFormat} class is defined by LDML's specification for
*
- * Compact Number Formats . A compact number formatting refers
- * to the representation of a number in a shorter form, based on the patterns
- * provided for a given locale.
+ * Compact Number Formats.
*
- *
- * For example:
- * In the {@link java.util.Locale#US US locale}, {@code 1000} can be formatted
- * as {@code "1K"}, and {@code 1000000} as {@code "1M"}, depending upon the
- * {@linkplain ##compact_number_style style} used.
- * In the {@code "hi_IN"} locale, {@code 1000} can be formatted as
- * "1 \u0939\u091C\u093C\u093E\u0930", and {@code 50000000} as "5 \u0915.",
- * depending upon the {@linkplain ##compact_number_style style} used.
+ *
Getting a CompactNumberFormat
+ * To get a compact number format, use one of the ways listed below.
+ *
+ * Use the factory method {@link NumberFormat#getCompactNumberInstance()}
+ * to obtain a format for the default locale with
+ * {@link NumberFormat.Style#SHORT SHORT} style.
+ * Use the factory methood {@link NumberFormat#getCompactNumberInstance(Locale, Style)}
+ * to obtain a format for a different locale
+ * and to control the {@linkplain ##compact_number_style Style}.
+ * Use one of the {@code CompactNumberFormat} constructors, for example, {@link
+ * CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
+ * CompactNumberFormat(decimalPattern, symbols, compactPatterns)}, to obtain a
+ * {@code CompactNumberFormat} with further customization.
+ *
+ * If a standard compact format for a given locale and {@link
+ * ##compact_number_style style} is desired, it is recommended to use one of the
+ * NumberFormat factory methods listed above. To use an instance method
+ * defined by {@code CompactNumberFormat}, the {@code NumberFormat} returned by
+ * these factory methods should be type checked before converted to {@code CompactNumberFormat}.
+ * If the installed locale-sensitive service implementation does not support
+ * the given {@code Locale}, the parent locale chain will be looked up, and
+ * a {@code Locale} used that is supported.
*
- *
- * To obtain a {@code CompactNumberFormat} for a locale, use one
- * of the factory methods given by {@code NumberFormat} for compact number
- * formatting. For example,
- * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
+ *
+ * When using {@link NumberFormat#getCompactNumberInstance(Locale, Style)}, a
+ * compact form can be retrieved with either a {@link NumberFormat.Style#SHORT
+ * SHORT} or {@link NumberFormat.Style#LONG LONG} style.
+ * For example, a {@link NumberFormat.Style#SHORT SHORT} style compact number instance in
+ * the {@link java.util.Locale#US US locale} formats {@code 10000} as {@code
+ * "10K"}. However, a {@link NumberFormat.Style#LONG LONG} style instance in
+ * the same locale formats {@code 10000} as {@code "10 thousand"}.
*
- * {@snippet lang=java :
- * NumberFormat fmt = NumberFormat.getCompactNumberInstance(
- * Locale.forLanguageTag("hi-IN"), NumberFormat.Style.SHORT);
- * String result = fmt.format(1000);
- * }
+ * Using CompactNumberFormat
+ * The following is an example of formatting and parsing in a localized manner,
*
- *
- *
- * A number can be formatted in the compact forms with two different
- * styles, {@link NumberFormat.Style#SHORT SHORT}
- * and {@link NumberFormat.Style#LONG LONG}. Use
- * {@link NumberFormat#getCompactNumberInstance(Locale, Style)} for formatting and
- * parsing a number in {@link NumberFormat.Style#SHORT SHORT} or
- * {@link NumberFormat.Style#LONG LONG} compact form,
- * where the given {@code Style} parameter requests the desired
- * format. A {@link NumberFormat.Style#SHORT SHORT} style
- * compact number instance in the {@link java.util.Locale#US US locale} formats
- * {@code 10000} as {@code "10K"}. However, a
- * {@link NumberFormat.Style#LONG LONG} style instance in same locale
- * formats {@code 10000} as {@code "10 thousand"}.
+ * {@snippet lang=java :
+ * NumberFormat compactFormat = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
+ * compactFormat.format(1000); // returns "1K"
+ * compactFormat.parse("1K"); // returns 1000
+ * }
+ *
+ *
+ * The default formatting behavior returns a formatted string with no fractional
+ * digits, however users can use the {@link #setMinimumFractionDigits(int)}
+ * method to include the fractional part.
+ * The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
+ * not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
+ * reason, the patterns provided for formatting contain only the minimum
+ * integer digits, prefix and/or suffix, but no fractional part.
+ * For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
+ * selected for formatting a number is {@code "0"} (special pattern),
+ * either explicit or defaulted, then the general number formatting provided by
+ * {@link java.text.DecimalFormat DecimalFormat}
+ * for the specified locale is used.
+ *
+ * Rounding
+ * {@code CompactNumberFormat} provides rounding modes defined in
+ * {@link java.math.RoundingMode} for formatting. By default, it uses
+ * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
+ *
+ * Parsing
+ * The default parsing behavior does not allow a grouping separator until
+ * grouping used is set to {@code true} by using
+ * {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
+ * depends on the {@link #isParseIntegerOnly()}. For example, if the
+ * parse integer only is set to true, then the fractional part is skipped.
*
*
*
- * The compact number patterns are represented in a series of patterns where each
- * pattern is used to format a range of numbers. An example of
- * {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
+ * The {@code compactPatterns} in {@link
+ * CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
+ * CompactNumberFormat(decimalPattern, symbols, compactPatterns)} are represented
+ * as a series of strings, where each string is a {@link ##compact_number_syntax
+ * pattern} that is used to format a range of numbers.
+ *
+ *
An example of the {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
* for the {@link java.util.Locale#US US locale} is {@code {"", "", "", "0K",
* "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"}},
* ranging from {@code 10}{@code 0} to {@code 10}{@code 14} .
* There can be any number of patterns and they are
* strictly index based starting from the range {@code 10}{@code 0} .
- * For example, in the above patterns, pattern at index 3
- * ({@code "0K"}) is used for formatting {@code number >= 1000 and number < 10000},
- * pattern at index 4 ({@code "00K"}) is used for formatting
- * {@code number >= 10000 and number < 100000} and so on. In most of the locales,
- * patterns with the range
+ * For example, in the above patterns, the pattern at index 3
+ * ({@code "0K"}) is used for formatting a number in the range: {@code 1000 <= number < 10000},
+ * index 4 ({@code "00K"}) for formatting a number the range: {@code 10000 <=
+ * number < 100000}, and so forth.
+ *
In most locales, patterns with the range
* {@code 10}{@code 0} -{@code 10}{@code 2} are empty
* strings, which implicitly means a special pattern {@code "0"}.
* A special pattern {@code "0"} is used for any range which does not contain
* a compact pattern. This special pattern can appear explicitly for any specific
* range, or considered as a default pattern for an empty string.
*
- *
+ *
Negative Subpatterns
* A compact pattern contains a positive and negative subpattern
- * separated by a subpattern boundary character {@code ';' (U+003B)},
+ * separated by a subpattern boundary character {@code ';'},
* for example, {@code "0K;-0K"}. Each subpattern has a prefix,
* minimum integer digits, and suffix. The negative subpattern
* is optional, if absent, then the positive subpattern prefixed with the
- * minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the negative
+ * minus sign {@code '-' (U+002D HYPHEN-MINUS)} is used as the negative
* subpattern. That is, {@code "0K"} alone is equivalent to {@code "0K;-0K"}.
* If there is an explicit negative subpattern, it serves only to specify
* the negative prefix and suffix. The number of minimum integer digits,
@@ -128,31 +161,35 @@
* That means that {@code "0K;-00K"} produces precisely the same behavior
* as {@code "0K;-0K"}.
*
- *
+ *
Escaping Special Characters
* Many characters in a compact pattern are taken literally, they are matched
* during parsing and output unchanged during formatting.
* {@linkplain DecimalFormat##special_pattern_character Special characters},
* on the other hand, stand for other characters, strings, or classes of
- * characters. They must be quoted, using single quote {@code ' (U+0027)}
+ * characters. These characters must be quoted using single quotes {@code ' (U+0027)}
* unless noted otherwise, if they are to appear in the prefix or suffix
* as literals. For example, 0\u0915'.'.
*
* Plurals
+ * {@code CompactNumberFormat} support patterns for both singular and plural
+ * compact forms. For the plural form, the {@code Pattern} should consist
+ * of {@code PluralPattern}(s) separated by a space ' ' (U+0020) that are enumerated
+ * within a pair of curly brackets '{' (U+007B) and '}' (U+007D).
+ * In this format, each {@code PluralPattern} consists of its {@code count},
+ * followed by a single colon {@code ':' (U+003A)} and a {@code SimplePattern}.
+ * As a space is reserved for separating subsequent {@code PluralPattern}s, it must
+ * be quoted to be used literally in either the {@code prefix} or {@code suffix}.
*
- * In case some localization requires compact number patterns to be different for
- * plurals, each singular and plural pattern can be enumerated within a pair of
- * curly brackets '{' (U+007B)
and '}' (U+007D)
, separated
- * by a space {@code ' ' (U+0020)}. If this format is used, each pattern needs to be
- * prepended by its {@code count}, followed by a single colon {@code ':' (U+003A)}.
- * If the pattern includes spaces literally, they must be quoted.
+ * For example, while the pattern representing millions ({@code 10}{@code 6}
+ * ) in the US locale can be specified as the SimplePattern: {@code "0 Million"}, for the
+ * German locale it can be specified as the PluralPattern:
+ * {@code "{one:0' 'Million other:0' 'Millionen}"}.
+ *
*
- * For example, the compact number pattern representing millions in German locale can be
- * specified as {@code "{one:0' 'Million other:0' 'Millionen}"}. The {@code count}
- * follows LDML's
+ * A compact pattern has the following syntax, with {@code count}
+ * following LDML's
*
- * Language Plural Rules .
- *
- * A compact pattern has the following syntax:
+ * Language Plural Rules:
*
* Pattern:
* SimplePattern
@@ -179,37 +216,12 @@
* 0 MinimumInteger
*
*
- * Formatting
- * The default formatting behavior returns a formatted string with no fractional
- * digits, however users can use the {@link #setMinimumFractionDigits(int)}
- * method to include the fractional part.
- * The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
- * not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
- * reason, the patterns provided for formatting contain only the minimum
- * integer digits, prefix and/or suffix, but no fractional part.
- * For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
- * selected for formatting a number is {@code "0"} (special pattern),
- * either explicit or defaulted, then the general number formatting provided by
- * {@link java.text.DecimalFormat DecimalFormat}
- * for the specified locale is used.
- *
- * Parsing
- * The default parsing behavior does not allow a grouping separator until
- * grouping used is set to {@code true} by using
- * {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
- * depends on the {@link #isParseIntegerOnly()}. For example, if the
- * parse integer only is set to true, then the fractional part is skipped.
- *
- * Rounding
- * {@code CompactNumberFormat} provides rounding modes defined in
- * {@link java.math.RoundingMode} for formatting. By default, it uses
- * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
- *
* @spec https://www.unicode.org/reports/tr35
* Unicode Locale Data Markup Language (LDML)
* @see NumberFormat.Style
* @see NumberFormat
* @see DecimalFormat
+ * @see Locale
* @since 12
*/
public final class CompactNumberFormat extends NumberFormat {
@@ -389,10 +401,19 @@ public final class CompactNumberFormat extends NumberFormat {
* To obtain the instance of {@code CompactNumberFormat} with the standard
* compact patterns for a {@code Locale} and {@code Style},
* it is recommended to use the factory methods given by
- * {@code NumberFormat} for compact number formatting. For example,
- * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
+ * {@code NumberFormat} for compact number formatting.
+ *
+ * Below is an example of using the constructor,
+ *
+ * {@snippet lang=java :
+ * String[] compactPatterns = {"", "", "", "a lot"};
+ * NumberFormat fmt = new CompactNumberFormat("00", DecimalFormatSymbols.getInstance(Locale.US), compactPatterns);
+ * fmt.format(1); // returns "01"
+ * fmt.format(1000); // returns "a lot"
+ * }
*
- * @param decimalPattern a decimal pattern for general number formatting
+ * @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
+ * for general number formatting
* @param symbols the set of symbols to be used
* @param compactPatterns an array of
* {@linkplain ##compact_number_patterns compact number patterns}
@@ -419,7 +440,8 @@ public CompactNumberFormat(String decimalPattern,
* {@code NumberFormat} for compact number formatting. For example,
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
*
- * @param decimalPattern a decimal pattern for general number formatting
+ * @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
+ * for general number formatting
* @param symbols the set of symbols to be used
* @param compactPatterns an array of
* {@linkplain ##compact_number_patterns compact number patterns}
diff --git a/src/java.base/share/classes/java/text/DateFormat.java b/src/java.base/share/classes/java/text/DateFormat.java
index d7a4b5a39b7..a67ba676836 100644
--- a/src/java.base/share/classes/java/text/DateFormat.java
+++ b/src/java.base/share/classes/java/text/DateFormat.java
@@ -407,7 +407,8 @@ public Date parse(String source) throws ParseException
/**
* Parse a date/time string according to the given parse position. For
- * example, a time text {@code "07/10/96 4:5 PM, PDT"} will be parsed into a {@code Date}
+ * example, if {@code this} has the pattern {@code "M/d/yy h:m a, z"},
+ * then a time text {@code "07/10/96 4:5 PM, PDT"} will be parsed into a {@code Date}
* that is equivalent to {@code Date(837039900000L)}.
*
*
By default, parsing is lenient: If the input is not in the form used
diff --git a/src/java.base/share/classes/java/text/DecimalFormat.java b/src/java.base/share/classes/java/text/DecimalFormat.java
index 752c3924855..2fc64d8e63e 100644
--- a/src/java.base/share/classes/java/text/DecimalFormat.java
+++ b/src/java.base/share/classes/java/text/DecimalFormat.java
@@ -56,45 +56,104 @@
/**
* {@code DecimalFormat} is a concrete subclass of
- * {@code NumberFormat} that formats decimal numbers. It has a variety of
- * features designed to make it possible to parse and format numbers in any
- * locale, including support for Western, Arabic, and Indic digits. It also
- * supports different kinds of numbers, including integers (123), fixed-point
+ * {@code NumberFormat} that formats decimal numbers in a localized manner.
+ * It has a variety of features designed to make it possible to parse and format
+ * numbers in any locale, including support for Western, Arabic, and Indic digits.
+ * It also supports different kinds of numbers, including integers (123), fixed-point
* numbers (123.4), scientific notation (1.23E4), percentages (12%), and
- * currency amounts ($123). All of these can be localized.
+ * currency amounts ($123).
*
- *
To obtain a {@code NumberFormat} for a specific locale, including the
- * default locale, call one of {@code NumberFormat}'s factory methods, such
- * as {@code getInstance()}. In general, do not call the
- * {@code DecimalFormat} constructors directly, since the
- * {@code NumberFormat} factory methods may return subclasses other than
- * {@code DecimalFormat}. If you need to customize the format object, do
- * something like this:
+ *
Getting a DecimalFormat
*
- * {@snippet lang=java :
- * NumberFormat numFormat = NumberFormat.getInstance(loc);
- * if (numFormat instanceof DecimalFormat decFormat) {
- * decFormat.setDecimalSeparatorAlwaysShown(true);
+ * To obtain a standard decimal format for a specific locale, including the default locale,
+ * it is recommended to call one of the {@code NumberFormat}
+ * {@link NumberFormat##factory_methods factory methods}, such as {@link NumberFormat#getInstance()}.
+ * These factory methods may not always return a {@code DecimalFormat}
+ * depending on the locale-service provider implementation
+ * installed. Thus, to use an instance method defined by {@code DecimalFormat},
+ * the {@code NumberFormat} returned by the factory method should be
+ * type checked before converted to {@code DecimalFormat}. If the installed locale-sensitive
+ * service implementation does not support the given {@code Locale}, the parent
+ * locale chain will be looked up, and a {@code Locale} used that is supported.
+ *
+ * If the factory methods are not desired, use one of the constructors such
+ * as {@link #DecimalFormat(String) DecimalFormat(String pattern)}. See the {@link
+ * ##patterns Pattern} section for more information on the {@code pattern} parameter.
+ *
+ *
Using DecimalFormat
+ * The following is an example of formatting and parsing,
+ * {@snippet lang=java :
+ * NumberFormat nFmt = NumberFormat.getCurrencyInstance(Locale.US);
+ * if (nFmt instanceof DecimalFormat dFmt) {
+ * // pattern match to DecimalFormat to use setPositiveSuffix(String)
+ * dFmt.setPositiveSuffix(" dollars");
+ * dFmt.format(100000); // returns "$100,000.00 dollars"
+ * dFmt.parse("$100,000.00 dollars"); // returns 100000
+ * }
* }
- * }
*
- * A {@code DecimalFormat} comprises a pattern and a set of
- * symbols . The pattern may be set directly using
- * {@code applyPattern()}, or indirectly using the API methods. The
- * symbols are stored in a {@code DecimalFormatSymbols} object. When using
- * the {@code NumberFormat} factory methods, the pattern and symbols are
- * read from localized {@code ResourceBundle}s.
*
- *
Patterns
+ *
+ * Rounding
*
- * Note: For any given {@code DecimalFormat} pattern, if the pattern is not
- * in scientific notation, the maximum number of integer digits will not be
- * derived from the pattern, and instead set to {@link Integer#MAX_VALUE}.
- * Otherwise, if the pattern is in scientific notation, the maximum number of
- * integer digits will be derived from the pattern. This derivation is detailed
- * in the {@link ##scientific_notation Scientific Notation} section. This behavior
- * is the typical end-user desire; {@link #setMaximumIntegerDigits(int)} can be
- * used to manually adjust the maximum integer digits.
+ * When formatting, {@code DecimalFormat} can adjust its rounding using {@link
+ * #setRoundingMode(RoundingMode)}. By default, it uses
+ * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
+ *
+ * Digits
+ *
+ * When formatting, {@code DecimalFormat} uses the ten consecutive
+ * characters starting with the localized zero digit defined in the
+ * {@code DecimalFormatSymbols} object as digits.
+ * When parsing, these digits as well as all Unicode decimal digits, as
+ * defined by {@link Character#digit Character.digit}, are recognized.
+ *
+ *
Integer and Fraction Digit Limits
+ * @implSpec
+ * When formatting a {@code Number} other than {@code BigInteger} and
+ * {@code BigDecimal}, {@code 309} is used as the upper limit for integer digits,
+ * and {@code 340} as the upper limit for fraction digits. This occurs, even if
+ * one of the {@code DecimalFormat} getter methods, for example, {@link #getMinimumFractionDigits()}
+ * returns a numerically greater value.
+ *
+ * Special Values
+ *
+ * Not a Number ({@code NaN}) is formatted as a string,
+ * which is typically given as "NaN". This string is determined by {@link
+ * DecimalFormatSymbols#getNaN()}. This is the only value for which the prefixes
+ * and suffixes are not attached.
+ *
+ *
Infinity is formatted as a string, which is typically given as
+ * "∞" ({@code U+221E}), with the positive or negative prefixes and suffixes
+ * attached. This string is determined by {@link DecimalFormatSymbols#getInfinity()}.
+ *
+ *
Negative zero ({@code "-0"}) parses to
+ *
+ * {@code BigDecimal(0)} if {@code isParseBigDecimal()} is
+ * true
+ * {@code Long(0)} if {@code isParseBigDecimal()} is false
+ * and {@code isParseIntegerOnly()} is true
+ * {@code Double(-0.0)} if both {@code isParseBigDecimal()}
+ * and {@code isParseIntegerOnly()} are false
+ *
+ *
+ *
+ *
+ *
+ *
+ * Decimal formats are generally not synchronized.
+ * It is recommended to create separate format instances for each thread.
+ * If multiple threads access a format concurrently, it must be synchronized
+ * externally.
+ *
+ *
DecimalFormat Pattern
+ *
+ * A {@code DecimalFormat} comprises a pattern and a set of
+ * symbols . The pattern may be set directly using {@code applyPattern()},
+ * or indirectly using the various API methods. The symbols are stored in a {@code
+ * DecimalFormatSymbols} object. When using the {@code NumberFormat} factory
+ * methods, the pattern and symbols are created from the locale-sensitive service
+ * implementation installed.
*
* {@code DecimalFormat} patterns have the following syntax:
*
@@ -135,50 +194,21 @@
* 0 MinimumExponentopt
*
*
- * A {@code DecimalFormat} pattern contains a positive and negative
- * subpattern, for example, {@code "#,##0.00;(#,##0.00)"}. Each
- * subpattern has a prefix, numeric part, and suffix. The negative subpattern
- * is optional; if absent, then the positive subpattern prefixed with the
- * minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the
- * negative subpattern. That is, {@code "0.00"} alone is equivalent to
- * {@code "0.00;-0.00"}. If there is an explicit negative subpattern, it
- * serves only to specify the negative prefix and suffix; the number of digits,
- * minimal digits, and other characteristics are all the same as the positive
- * pattern. That means that {@code "#,##0.0#;(#)"} produces precisely
- * the same behavior as {@code "#,##0.0#;(#,##0.0#)"}.
- *
- *
The prefixes, suffixes, and various symbols used for infinity, digits,
- * grouping separators, decimal separators, etc. may be set to arbitrary
- * values, and they will appear properly during formatting. However, care must
- * be taken that the symbols and strings do not conflict, or parsing will be
- * unreliable. For example, either the positive and negative prefixes or the
- * suffixes must be distinct for {@code DecimalFormat.parse()} to be able
- * to distinguish positive from negative values. (If they are identical, then
- * {@code DecimalFormat} will behave as if no negative subpattern was
- * specified.) Another example is that the decimal separator and grouping
- * separator should be distinct characters, or parsing will be impossible.
- *
- *
The grouping separator is commonly used for thousands, but in some
- * countries it separates ten-thousands. The grouping size is a constant number
- * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
- * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
- * interval between the last one and the end of the integer is the one that is
- * used. So {@code "#,##,###,####"} == {@code "######,####"} ==
- * {@code "##,####,####"}.
- *
*
*
- * Many characters in a pattern are taken literally; they are matched during
- * parsing and output unchanged during formatting. Special characters, on the
- * other hand, stand for other characters, strings, or classes of characters.
+ *
The special characters in the table below are interpreted syntactically when
+ * used in the DecimalFormat pattern.
* They must be quoted, unless noted otherwise, if they are to appear in the
* prefix or suffix as literals.
*
- *
The characters listed here are used in non-localized patterns. Localized
- * patterns use the corresponding characters taken from this formatter's
- * {@code DecimalFormatSymbols} object instead, and these characters lose
- * their special status. Two exceptions are the currency sign and quote, which
- * are not localized.
+ *
The characters in the {@code Symbol} column are used in non-localized
+ * patterns. The corresponding characters in the {@code Localized Symbol} column are used
+ * in localized patterns, with the characters in {@code Symbol} losing their
+ * syntactical meaning. Two exceptions are the currency sign ({@code U+00A4}) and
+ * quote ({@code U+0027}), which are not localized.
+ *
+ * Non-localized patterns should be used when calling {@link #applyPattern(String)}.
+ * Localized patterns should be used when calling {@link #applyLocalizedPattern(String)}.
*
*
*
@@ -186,69 +216,69 @@
*
*
* Symbol
+ * Localized Symbol
* Location
- * Localized?
- * Meaning
+ * Meaning
*
*
- *
+ *
* {@code 0}
+ * {@link DecimalFormatSymbols#getZeroDigit()}
* Number
- * Yes
* Digit
- *
+ *
* {@code #}
+ * {@link DecimalFormatSymbols#getDigit()}
* Number
- * Yes
* Digit, zero shows as absent
- *
+ *
* {@code .}
+ * {@link DecimalFormatSymbols#getDecimalSeparator()}
* Number
- * Yes
* Decimal separator or monetary decimal separator
- *
- * {@code -}
+ *
+ * {@code - (U+002D)}
+ * {@link DecimalFormatSymbols#getMinusSign()}
* Number
- * Yes
* Minus sign
- *
+ *
* {@code ,}
+ * {@link DecimalFormatSymbols#getGroupingSeparator()}
* Number
- * Yes
* Grouping separator or monetary grouping separator
- *
+ *
* {@code E}
+ * {@link DecimalFormatSymbols#getExponentSeparator()}
* Number
- * Yes
- * Separates mantissa and exponent in scientific notation.
- * Need not be quoted in prefix or suffix.
- *
+ * Separates mantissa and exponent in scientific notation. This value
+ * is case sensistive. Need not be quoted in prefix or suffix.
+ *
* {@code ;}
+ * {@link DecimalFormatSymbols#getPatternSeparator()}
* Subpattern boundary
- * Yes
* Separates positive and negative subpatterns
- *
+ *
* {@code %}
+ * {@link DecimalFormatSymbols#getPercent()}
* Prefix or suffix
- * Yes
* Multiply by 100 and show as percentage
- *
- * {@code U+2030}
+ *
+ * ‰ ({@code U+2030})
+ * {@link DecimalFormatSymbols#getPerMill()}
* Prefix or suffix
- * Yes
* Multiply by 1000 and show as per mille value
- *
+ *
* ¤ ({@code U+00A4})
+ * n/a (not localized)
* Prefix or suffix
- * No
* Currency sign, replaced by currency symbol. If
* doubled, replaced by international currency symbol.
* If present in a pattern, the monetary decimal/grouping separators
* are used instead of the decimal/grouping separators.
- *
- * {@code '}
+ *
+ * {@code ' (U+0027)}
+ * n/a (not localized)
* Prefix or suffix
- * No
* Used to quote special characters in a prefix or suffix,
* for example, {@code "'#'#"} formats 123 to
* {@code "#123"}. To create a single quote
@@ -257,6 +287,49 @@
*
*
*
+ * Maximum Digits Derivation
+ * For any given {@code DecimalFormat} pattern, if the pattern is not
+ * in scientific notation, the maximum number of integer digits will not be
+ * derived from the pattern, and instead set to {@link Integer#MAX_VALUE}.
+ * Otherwise, if the pattern is in scientific notation, the maximum number of
+ * integer digits will be derived from the pattern. This derivation is detailed
+ * in the {@link ##scientific_notation Scientific Notation} section. {@link
+ * #setMaximumIntegerDigits(int)} can be used to manually adjust the maximum
+ * integer digits.
+ *
+ * Negative Subpatterns
+ * A {@code DecimalFormat} pattern contains a positive and negative
+ * subpattern, for example, {@code "#,##0.00;(#,##0.00)"}. Each
+ * subpattern has a prefix, numeric part, and suffix. The negative subpattern
+ * is optional; if absent, then the positive subpattern prefixed with the
+ * minus sign {@code '-' (U+002D HYPHEN-MINUS)} is used as the
+ * negative subpattern. That is, {@code "0.00"} alone is equivalent to
+ * {@code "0.00;-0.00"}. If there is an explicit negative subpattern, it
+ * serves only to specify the negative prefix and suffix; the number of digits,
+ * minimal digits, and other characteristics are all the same as the positive
+ * pattern. That means that {@code "#,##0.0#;(#)"} produces precisely
+ * the same behavior as {@code "#,##0.0#;(#,##0.0#)"}.
+ *
+ * The prefixes, suffixes, and various symbols used for infinity, digits,
+ * grouping separators, decimal separators, etc. may be set to arbitrary
+ * values, and they will appear properly during formatting. However, care must
+ * be taken that the symbols and strings do not conflict, or parsing will be
+ * unreliable. For example, either the positive and negative prefixes or the
+ * suffixes must be distinct for {@code DecimalFormat.parse()} to be able
+ * to distinguish positive from negative values. (If they are identical, then
+ * {@code DecimalFormat} will behave as if no negative subpattern was
+ * specified.) Another example is that the decimal separator and grouping
+ * separator should be distinct characters, or parsing will be impossible.
+ *
+ *
Grouping Separator
+ * The grouping separator is commonly used for thousands, but in some
+ * locales it separates ten-thousands. The grouping size is a constant number
+ * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
+ * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
+ * interval between the last one and the end of the integer is the one that is
+ * used. For example, {@code "#,##,###,####"} == {@code "######,####"} ==
+ * {@code "##,####,####"}.
+ *
*
Scientific Notation
*
* Numbers in scientific notation are expressed as the product of a mantissa
@@ -339,95 +412,13 @@
*
Exponential patterns may not contain grouping separators.
*
*
- * Rounding
- *
- * {@code DecimalFormat} provides rounding modes defined in
- * {@link java.math.RoundingMode} for formatting. By default, it uses
- * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
- *
- * Digits
- *
- * For formatting, {@code DecimalFormat} uses the ten consecutive
- * characters starting with the localized zero digit defined in the
- * {@code DecimalFormatSymbols} object as digits. For parsing, these
- * digits as well as all Unicode decimal digits, as defined by
- * {@link Character#digit Character.digit}, are recognized.
- *
- * Integer and Fraction Digit Limits
- *
- * @implSpec
- * When formatting a {@code Number} other than {@code BigInteger} and
- * {@code BigDecimal}, {@code 309} is used as the upper limit for integer digits,
- * and {@code 340} as the upper limit for fraction digits. This occurs, even if
- * one of the {@code DecimalFormat} getter methods, for example, {@link #getMinimumFractionDigits()}
- * returns a numerically greater value.
- *
- * Special Values
- *
- * Not a Number({@code NaN}) is formatted as a string, which typically has a
- * single character {@code U+FFFD}. This string is determined by the
- * {@code DecimalFormatSymbols} object. This is the only value for which
- * the prefixes and suffixes are not used.
- *
- *
Infinity is formatted as a string, which typically has a single character
- * {@code U+221E}, with the positive or negative prefixes and suffixes
- * applied. The infinity string is determined by the
- * {@code DecimalFormatSymbols} object.
- *
- *
Negative zero ({@code "-0"}) parses to
- *
- * {@code BigDecimal(0)} if {@code isParseBigDecimal()} is
- * true,
- * {@code Long(0)} if {@code isParseBigDecimal()} is false
- * and {@code isParseIntegerOnly()} is true,
- * {@code Double(-0.0)} if both {@code isParseBigDecimal()}
- * and {@code isParseIntegerOnly()} are false.
- *
- *
- *
- *
- *
- * Decimal formats are generally not synchronized.
- * It is recommended to create separate format instances for each thread.
- * If multiple threads access a format concurrently, it must be synchronized
- * externally.
- *
- *
Example
- *
- * {@snippet lang=java :
- * // Print out a number using the localized number, integer, currency,
- * // and percent format for each locale
- * Locale[] locales = NumberFormat.getAvailableLocales();
- * double myNumber = -1234.56;
- * NumberFormat form;
- * for (int j = 0; j < 4; ++j) {
- * System.out.println("FORMAT");
- * for (Locale locale : locales) {
- * if (locale.getCountry().length() == 0) {
- * continue; // Skip language-only locales
- * }
- * System.out.print(locale.getDisplayName());
- * form = switch (j) {
- * case 0 -> NumberFormat.getInstance(locale);
- * case 1 -> NumberFormat.getIntegerInstance(locale);
- * case 2 -> NumberFormat.getCurrencyInstance(locale);
- * default -> NumberFormat.getPercentInstance(locale);
- * };
- * if (form instanceof DecimalFormat decForm) {
- * System.out.print(": " + decForm.toPattern());
- * }
- * System.out.print(" -> " + form.format(myNumber));
- * try {
- * System.out.println(" -> " + form.parse(form.format(myNumber)));
- * } catch (ParseException e) {}
- * }
- * }
- * }
- *
+ * @spec https://www.unicode.org/reports/tr35
+ * Unicode Locale Data Markup Language (LDML)
* @see Java Tutorial
* @see NumberFormat
* @see DecimalFormatSymbols
* @see ParsePosition
+ * @see Locale
* @author Mark Davis
* @author Alan Liu
* @since 1.1
diff --git a/src/java.base/share/classes/java/text/NumberFormat.java b/src/java.base/share/classes/java/text/NumberFormat.java
index bd36ad6dc25..0409efc2da0 100644
--- a/src/java.base/share/classes/java/text/NumberFormat.java
+++ b/src/java.base/share/classes/java/text/NumberFormat.java
@@ -59,102 +59,110 @@
/**
* {@code NumberFormat} is the abstract base class for all number
* formats. This class provides the interface for formatting and parsing
- * numbers. {@code NumberFormat} also provides methods for determining
- * which locales have number formats, and what their names are.
+ * numbers in a localized manner. This enables code that can be completely
+ * independent of the locale conventions for decimal points, thousands-separators,
+ * the particular decimal digits used, or whether the number format is even
+ * decimal. For example, this class could be used within an application to
+ * produce a number in a currency format according to the conventions of the desired
+ * locale.
*
- *
- * {@code NumberFormat} helps you to format and parse numbers for any locale.
- * Your code can be completely independent of the locale conventions for
- * decimal points, thousands-separators, or even the particular decimal
- * digits used, or whether the number format is even decimal.
+ *
Getting a NumberFormat
+ * To get a {@code NumberFormat} for the default Locale, use one of the static
+ * factory methods that return a concrete subclass of {@code NumberFormat}.
+ * The following formats all provide an example of formatting the {@code Number}
+ * "2000.50" with the {@link java.util.Locale#US US} locale as the default locale.
+ *
+ * Use {@link #getInstance()} or {@link #getNumberInstance()} to get
+ * a decimal format. For example, {@code "2,000.5"}.
+ * Use {@link #getIntegerInstance()} to get an integer number format.
+ * For example, {@code "2,000"}.
+ * Use {@link #getCurrencyInstance} to get a currency number format.
+ * For example, {@code "$2,000.50"}.
+ * Use {@link #getCompactNumberInstance} to get a compact number format.
+ * For example, {@code "2K"}.
+ * Use {@link #getPercentInstance} to get a format for displaying percentages.
+ * For example, {@code "200,050%"}.
+ *
*
- *
- * To format a number for the current Locale, use one of the factory
- * class methods:
- *
- * {@snippet lang=java :
- * myString = NumberFormat.getInstance().format(myNumber);
- * }
- *
- * If you are formatting multiple numbers, it is
- * more efficient to get the format and use it multiple times so that
- * the system doesn't have to fetch the information about the local
- * language and country conventions multiple times.
- *
- * {@snippet lang=java :
- * NumberFormat nf = NumberFormat.getInstance();
- * for (var myNumber : numbers) {
- * output.println(nf.format(myNumber) + "; ");
- * }
- * }
- *
- * To format a number for a different Locale, specify it in the
- * call to {@code getInstance}.
- *
- * {@snippet lang=java :
- * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
- * }
- *
+ * Alternatively, if a {@code NumberFormat} for a different locale is required, use
+ * one of the overloaded factory methods that take {@code Locale} as a parameter,
+ * for example, {@link #getIntegerInstance(Locale)}. If the installed locale-sensitive
+ * service implementation does not support the given {@code Locale}, the parent
+ * locale chain will be looked up, and a {@code Locale} used that is supported.
*
- * If the locale contains "nu" (numbers) and/or "rg" (region override)
+ *
Locale Extensions
+ * Formatting behavior can be changed when using a locale that contains any of the following
* Unicode extensions ,
- * the decimal digits, and/or the country used for formatting are overridden.
+ *
+ *
* If both "nu" and "rg" are specified, the decimal digits from the "nu"
* extension supersedes the implicit one from the "rg" extension.
+ * Although Unicode extensions
+ * defines various keys and values, actual locale-sensitive service implementations
+ * in a Java Runtime Environment might not support any particular Unicode locale
+ * attributes or key/type pairs.
+ *
Below is an example of a "US" locale currency format with accounting style,
+ *
{@code NumberFormat.getCurrencyInstance(Locale.forLanguageTag("en-US-u-cf-account"));}
+ * With this style, a negative value is formatted enclosed in parentheses, instead
+ * of being prepended with a minus sign.
*
- * You can also use a {@code NumberFormat} to parse numbers:
- *
+ * Using NumberFormat
+ * The following is an example of formatting and parsing in a localized fashion,
* {@snippet lang=java :
- * myNumber = nf.parse(myString);
+ * NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
+ * currencyFormat.format(100000); // returns "$100,000.00"
+ * currencyFormat.parse("$100,000.00"); // returns 100000
* }
- *
- * Use {@code getInstance} or {@code getNumberInstance} to get the
- * normal number format. Use {@code getIntegerInstance} to get an
- * integer number format. Use {@code getCurrencyInstance} to get the
- * currency number format. Use {@code getCompactNumberInstance} to get the
- * compact number format to format a number in shorter form. For example,
- * {@code 2000} can be formatted as {@code "2K"} in
- * {@link java.util.Locale#US US locale}. Use {@code getPercentInstance}
- * to get a format for displaying percentages. With this format, a fraction
- * like 0.53 is displayed as 53%.
*
- *
- * You can also control the display of numbers with such methods as
- * {@code setMinimumFractionDigits}.
- * If you want even more control over the format or parsing,
- * or want to give your users more control,
- * you can try casting the {@code NumberFormat} you get from the factory methods
- * to a {@code DecimalFormat} or {@code CompactNumberFormat} depending on
- * the factory method used. This will work for the vast majority of locales;
- * just remember to put it in a {@code try} block in case you encounter
- * an unusual one.
+ *
Customizing NumberFormat
+ * {@code NumberFormat} provides API to customize formatting and parsing behavior,
+ *
+ * {@link #setParseIntegerOnly(boolean)}; when {@code true}, will only return the
+ * integer portion of the number parsed from the String.
+ * {@link #setMinimumFractionDigits(int)}; Use to adjust the expected digits when
+ * formatting. Use any of the other minimum/maximum or fraction/integer setter methods
+ * in the same manner.
+ * {@link #setGroupingUsed(boolean)}; when {@code true}, formatted numbers will be displayed
+ * with grouping separators. Additionally, when {@code false}, parsing will not expect
+ * grouping separators in the parsed String.
+ * {@link #setStrict(boolean)}; when {@code true}, parsing will be done strictly.
+ * The behavior of strict parsing should be referred to in the implementing
+ * {@code NumberFormat} subclass.
+ *
*
*
- * NumberFormat and DecimalFormat are designed such that some controls
- * work for formatting and others work for parsing. The following is
- * the detailed description for each these control methods,
- *
- * setParseIntegerOnly : only affects parsing, e.g.
- * if true, "3456.78" → 3456 (and leaves the parse position just after index 6)
- * if false, "3456.78" → 3456.78 (and leaves the parse position just after index 8)
- * This is independent of formatting. If you want to not show a decimal point
- * where there might be no digits after the decimal point, use
- * setDecimalSeparatorAlwaysShown.
- *
- * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
- * there might be no digits after the decimal point, such as with a pattern
- * like "#,##0.##", e.g.,
- * if true, 3456.00 → "3,456."
- * if false, 3456.00 → "3456"
- * This is independent of parsing. If you want parsing to stop at the decimal
- * point, use setParseIntegerOnly.
+ * To provide more control over formatting or parsing behavior, type checking can
+ * be done to safely convert to an implementing subclass of {@code NumberFormat}; this
+ * provides additional methods defined by the subclass.
+ * For example,
+ * {@snippet lang=java :
+ * NumberFormat nFmt = NumberFormat.getInstance(Locale.US);
+ * if (nFmt instanceof DecimalFormat dFmt) {
+ * dFmt.setDecimalSeparatorAlwaysShown(true);
+ * dFmt.format(100); // returns "100."
+ * }
+ * }
+ * The {@code NumberFormat} subclass returned by the factory methods is dependent
+ * on the locale-service provider implementation installed, and may not always
+ * be {@link DecimalFormat} or {@link CompactNumberFormat}.
+ *
*
* You can also use forms of the {@code parse} and {@code format}
* methods with {@code ParsePosition} and {@code FieldPosition} to
* allow you to:
*
- * progressively parse through pieces of a string
- * align the decimal point and other areas
+ * Progressively parse through pieces of a string
+ * Align the decimal point and other areas
*
* For example, you can align numbers in two ways:
*
@@ -197,15 +205,20 @@
* If multiple threads access a format concurrently, it must be synchronized
* externally.
*
- * @implSpec The {@link #format(double, StringBuffer, FieldPosition)},
+ * @implSpec
+ * Null Parameter Handling
+ *
+ * The {@link #format(double, StringBuffer, FieldPosition)},
* {@link #format(long, StringBuffer, FieldPosition)} and
* {@link #parse(String, ParsePosition)} methods may throw
* {@code NullPointerException}, if any of their parameter is {@code null}.
* The subclass may provide its own implementation and specification about
* {@code NullPointerException}.
+ *
*
- *
- * The default implementation provides rounding modes defined
+ * Default RoundingMode
+ *
+ * The default implementation provides rounding modes defined
* in {@link java.math.RoundingMode} for formatting numbers. It
* uses the {@linkplain java.math.RoundingMode#HALF_EVEN
* round half-even algorithm}. To change the rounding mode use
@@ -214,10 +227,14 @@
* configured to round floating point numbers using half-even
* rounding (see {@link java.math.RoundingMode#HALF_EVEN
* RoundingMode.HALF_EVEN}) for formatting.
+ *
*
+ * @spec https://www.unicode.org/reports/tr35
+ * Unicode Locale Data Markup Language (LDML)
* @see DecimalFormat
* @see ChoiceFormat
* @see CompactNumberFormat
+ * @see Locale
* @author Mark Davis
* @author Helena Shih
* @since 1.1
diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java
index bcdf32d6f8b..0f8474ec12d 100644
--- a/src/java.base/share/classes/java/util/Locale.java
+++ b/src/java.base/share/classes/java/util/Locale.java
@@ -995,11 +995,11 @@ static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
private static final ReferencedKeyMap LOCALE_CACHE = ReferencedKeyMap.create(true, ConcurrentHashMap::new);
private static Locale createLocale(Object key) {
- return switch (key) {
- case BaseLocale base -> new Locale(base, null);
- case LocaleKey lk -> new Locale(lk.base, lk.exts);
- default -> throw new InternalError("should not happen");
- };
+ if (key instanceof BaseLocale base) {
+ return new Locale(base, null);
+ }
+ LocaleKey lk = (LocaleKey)key;
+ return new Locale(lk.base, lk.exts);
}
private static final class LocaleKey {
diff --git a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java
index f45c0036230..1b1ba4b29a0 100644
--- a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java
+++ b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java
@@ -117,6 +117,7 @@ protected RunnableFuture newTaskFor(Callable callable) {
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
+ @Override
public Future> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task, null);
@@ -128,6 +129,7 @@ public Future> submit(Runnable task) {
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
+ @Override
public Future submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task, result);
@@ -139,6 +141,7 @@ public Future submit(Runnable task, T result) {
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
+ @Override
public Future submit(Callable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task);
@@ -219,6 +222,14 @@ else if (timed) {
}
}
+ /**
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ExecutionException {@inheritDoc}
+ * @throws RejectedExecutionException {@inheritDoc}
+ */
+ @Override
public T invokeAny(Collection extends Callable> tasks)
throws InterruptedException, ExecutionException {
try {
@@ -229,12 +240,26 @@ public T invokeAny(Collection extends Callable> tasks)
}
}
+ /**
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws TimeoutException {@inheritDoc}
+ * @throws ExecutionException {@inheritDoc}
+ * @throws RejectedExecutionException {@inheritDoc}
+ */
+ @Override
public T invokeAny(Collection extends Callable> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
+ /**
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws RejectedExecutionException {@inheritDoc}
+ */
+ @Override
public List> invokeAll(Collection extends Callable> tasks)
throws InterruptedException {
if (tasks == null)
@@ -260,6 +285,12 @@ public List> invokeAll(Collection extends Callable> tasks)
}
}
+ /**
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws RejectedExecutionException {@inheritDoc}
+ */
+ @Override
public List> invokeAll(Collection extends Callable> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java
index 1c2fd151b8d..62ef125fdee 100644
--- a/src/java.base/share/classes/java/util/regex/Pattern.java
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java
@@ -2225,7 +2225,7 @@ private static final boolean isSupplementary(int ch) {
Character.isSurrogate((char)ch);
}
- /**
+ /*
* The following methods handle the main parsing. They are sorted
* according to their precedence order, the lowest one first.
*/
@@ -2282,10 +2282,10 @@ private Node expr(Node end) {
}
}
- @SuppressWarnings("fallthrough")
/**
* Parsing of sequences between alternations.
*/
+ @SuppressWarnings("fallthrough")
private Node sequence(Node end) {
Node head = null;
Node tail = null;
@@ -2409,10 +2409,10 @@ private Node sequence(Node end) {
return head;
}
- @SuppressWarnings("fallthrough")
/**
* Parse and add a new Single or Slice.
*/
+ @SuppressWarnings("fallthrough")
private Node atom() {
int first = 0;
int prev = -1;
@@ -3322,10 +3322,10 @@ private Node createGroup(boolean anonymous) {
return head;
}
- @SuppressWarnings("fallthrough")
/**
* Parses inlined match flags and set them appropriately.
*/
+ @SuppressWarnings("fallthrough")
private void addFlag() {
int ch = peek();
for (;;) {
@@ -3364,11 +3364,11 @@ private void addFlag() {
}
}
- @SuppressWarnings("fallthrough")
/**
* Parses the second part of inlined match flags and turns off
* flags appropriately.
*/
+ @SuppressWarnings("fallthrough")
private void subFlag() {
int ch = peek();
for (;;) {
@@ -3708,7 +3708,7 @@ private Node newSlice(int[] buf, int count, boolean hasSupplementary) {
return hasSupplementary ? new SliceS(tmp) : new Slice(tmp);
}
- /**
+ /*
* The following classes are the building components of the object
* tree that represents a compiled regular expression. The object tree
* is made of individual elements that handle constructs in the Pattern.
diff --git a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
index 86aa580b619..2bf0c711cfe 100644
--- a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
+++ b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
@@ -159,6 +159,8 @@
* CLDR version
*
*
+ * JDK 23
+ * CLDR 45
* JDK 22
* CLDR 44
* JDK 21
diff --git a/src/java.base/share/classes/javax/crypto/CipherInputStream.java b/src/java.base/share/classes/javax/crypto/CipherInputStream.java
index d9b8c989b54..546bdf0808d 100644
--- a/src/java.base/share/classes/javax/crypto/CipherInputStream.java
+++ b/src/java.base/share/classes/javax/crypto/CipherInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,8 +84,8 @@ public class CipherInputStream extends FilterInputStream {
/* the buffer holding data that have been read in from the
underlying stream, but have not been processed by the cipher
- engine. the size 512 bytes is somewhat randomly chosen */
- private final byte[] ibuffer = new byte[512];
+ engine. */
+ private final byte[] ibuffer = new byte[8192];
// having reached the end of the underlying input stream
private boolean done = false;
diff --git a/src/java.base/share/classes/jdk/internal/access/JavaAWTFontAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaAWTFontAccess.java
index 6a5102b5088..139f02450b8 100644
--- a/src/java.base/share/classes/jdk/internal/access/JavaAWTFontAccess.java
+++ b/src/java.base/share/classes/jdk/internal/access/JavaAWTFontAccess.java
@@ -23,12 +23,12 @@
* questions.
*/
+package jdk.internal.access;
+
/**
* SharedSecrets interface used for the access from java.text.Bidi
*/
-package jdk.internal.access;
-
public interface JavaAWTFontAccess {
// java.awt.font.TextAttribute constants
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java
index 1ee9e1136a5..4e9a55c77ac 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java
@@ -262,6 +262,9 @@ public static final class BoundLookupSwitchInstruction
this.afterPad = pos + 1 + ((4 - ((pos + 1 - code.codeStart) & 3)) & 3);
this.npairs = code.classReader.readInt(afterPad + 4);
+ if (npairs < 0 || npairs > code.codeLength >> 3) {
+ throw new IllegalArgumentException("Invalid lookupswitch npairs value: " + npairs);
+ }
}
static int size(CodeImpl code, int codeStart, int pos) {
@@ -314,6 +317,9 @@ static int size(CodeImpl code, int codeStart, int pos) {
int pad = ap - (pos + 1);
int low = code.classReader.readInt(ap + 4);
int high = code.classReader.readInt(ap + 8);
+ if (high < low || high - low > code.codeLength >> 2) {
+ throw new IllegalArgumentException("Invalid tableswitch values low: " + low + " high: " + high);
+ }
int cnt = high - low + 1;
return 1 + pad + 12 + cnt * 4;
}
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/CatchBuilderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/CatchBuilderImpl.java
index 0878682ae56..5d262c397f6 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/CatchBuilderImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/CatchBuilderImpl.java
@@ -62,7 +62,7 @@ public CodeBuilder.CatchBuilder catchingMulti(List exceptionTypes, Co
if (catchBlock == null) {
if (tryBlock.reachable()) {
- b.branchInstruction(Opcode.GOTO, tryCatchEnd);
+ b.branch(Opcode.GOTO, tryCatchEnd);
}
}
@@ -76,7 +76,7 @@ public CodeBuilder.CatchBuilder catchingMulti(List exceptionTypes, Co
if (catchBlock != null) {
catchBlock.end();
if (catchBlock.reachable()) {
- b.branchInstruction(Opcode.GOTO, tryCatchEnd);
+ b.branch(Opcode.GOTO, tryCatchEnd);
}
}
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
index 9b6c7d7ad4c..2022f8f0154 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
@@ -150,7 +150,7 @@ public int flags() {
@Override
public ClassEntry thisClassEntry() {
if (thisClass == null) {
- thisClass = readEntry(thisClassPos, ClassEntry.class);
+ thisClass = readClassEntry(thisClassPos);
}
return thisClass;
}
@@ -339,6 +339,10 @@ void writeConstantPoolEntries(BufWriter buf) {
// Constantpool
@Override
public PoolEntry entryByIndex(int index) {
+ return entryByIndex(index, 0, 0xff);
+ }
+
+ private PoolEntry entryByIndex(int index, int lowerBoundTag, int upperBoundTag) {
if (index <= 0 || index >= constantPoolCount) {
throw new ConstantPoolException("Bad CP index: " + index);
}
@@ -349,6 +353,10 @@ public PoolEntry entryByIndex(int index) {
throw new ConstantPoolException("Unusable CP index: " + index);
}
int tag = readU1(offset);
+ if (tag < lowerBoundTag || tag > upperBoundTag) {
+ throw new ConstantPoolException(
+ "Bad tag (" + tag + ") at index (" + index + ") position (" + offset + ")");
+ }
final int q = offset + 1;
info = switch (tag) {
case TAG_UTF8 -> new AbstractPoolEntry.Utf8EntryImpl(this, index, buffer, q + 2, readU2(q));
@@ -367,7 +375,7 @@ public PoolEntry entryByIndex(int index) {
case TAG_NAMEANDTYPE -> new AbstractPoolEntry.NameAndTypeEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q),
(AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q + 2));
case TAG_METHODHANDLE -> new AbstractPoolEntry.MethodHandleEntryImpl(this, index, readU1(q),
- (AbstractPoolEntry.AbstractMemberRefEntry) readEntry(q + 1));
+ readEntry(q + 1, AbstractPoolEntry.AbstractMemberRefEntry.class, TAG_FIELDREF, TAG_INTERFACEMETHODREF));
case TAG_METHODTYPE -> new AbstractPoolEntry.MethodTypeEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q));
case TAG_CONSTANTDYNAMIC -> new AbstractPoolEntry.ConstantDynamicEntryImpl(this, index, readU2(q), (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2));
case TAG_INVOKEDYNAMIC -> new AbstractPoolEntry.InvokeDynamicEntryImpl(this, index, readU2(q), (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2));
@@ -423,7 +431,15 @@ public PoolEntry readEntry(int pos) {
@Override
public T readEntry(int pos, Class cls) {
- var e = readEntry(pos);
+ return readEntry(pos, cls, 0, 0xff);
+ }
+
+ private T readEntry(int pos, Class cls, int expectedTag) {
+ return readEntry(pos, cls, expectedTag, expectedTag);
+ }
+
+ private T readEntry(int pos, Class cls, int lowerBoundTag, int upperBoundTag) {
+ var e = entryByIndex(readU2(pos), lowerBoundTag, upperBoundTag);
if (cls.isInstance(e)) return cls.cast(e);
throw new ConstantPoolException("Not a " + cls.getSimpleName() + " at index: " + readU2(pos));
}
@@ -454,27 +470,27 @@ public Utf8Entry readUtf8EntryOrNull(int pos) {
@Override
public ModuleEntry readModuleEntry(int pos) {
- return readEntry(pos, ModuleEntry.class);
+ return readEntry(pos, ModuleEntry.class, TAG_MODULE);
}
@Override
public PackageEntry readPackageEntry(int pos) {
- return readEntry(pos, PackageEntry.class);
+ return readEntry(pos, PackageEntry.class, TAG_PACKAGE);
}
@Override
public ClassEntry readClassEntry(int pos) {
- return readEntry(pos, ClassEntry.class);
+ return readEntry(pos, ClassEntry.class, TAG_CLASS);
}
@Override
public NameAndTypeEntry readNameAndTypeEntry(int pos) {
- return readEntry(pos, NameAndTypeEntry.class);
+ return readEntry(pos, NameAndTypeEntry.class, TAG_NAMEANDTYPE);
}
@Override
public MethodHandleEntry readMethodHandleEntry(int pos) {
- return readEntry(pos, MethodHandleEntry.class);
+ return readEntry(pos, MethodHandleEntry.class, TAG_METHODHANDLE);
}
@Override
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java
index 8f35b85b5de..6e80e289064 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java
@@ -231,25 +231,25 @@ public CodeTransform asCodeTransform() {
return (CodeBuilder cob, CodeElement coe) -> {
switch (coe) {
case FieldInstruction fai ->
- cob.fieldInstruction(fai.opcode(), map(fai.owner().asSymbol()),
+ cob.fieldAccess(fai.opcode(), map(fai.owner().asSymbol()),
fai.name().stringValue(), map(fai.typeSymbol()));
case InvokeInstruction ii ->
- cob.invokeInstruction(ii.opcode(), map(ii.owner().asSymbol()),
+ cob.invoke(ii.opcode(), map(ii.owner().asSymbol()),
ii.name().stringValue(), mapMethodDesc(ii.typeSymbol()),
ii.isInterface());
case InvokeDynamicInstruction idi ->
- cob.invokeDynamicInstruction(DynamicCallSiteDesc.of(
+ cob.invokedynamic(DynamicCallSiteDesc.of(
idi.bootstrapMethod(), idi.name().stringValue(),
mapMethodDesc(idi.typeSymbol()),
idi.bootstrapArgs().stream().map(this::mapConstantValue).toArray(ConstantDesc[]::new)));
case NewObjectInstruction c ->
- cob.newObjectInstruction(map(c.className().asSymbol()));
+ cob.new_(map(c.className().asSymbol()));
case NewReferenceArrayInstruction c ->
cob.anewarray(map(c.componentType().asSymbol()));
case NewMultiArrayInstruction c ->
cob.multianewarray(map(c.arrayType().asSymbol()), c.dimensions());
case TypeCheckInstruction c ->
- cob.typeCheckInstruction(c.opcode(), map(c.type().asSymbol()));
+ cob.with(TypeCheckInstruction.of(c.opcode(), map(c.type().asSymbol())));
case ExceptionCatch c ->
cob.exceptionCatch(c.tryStart(), c.tryEnd(), c.handler(),c.catchType()
.map(d -> TemporaryConstantPool.INSTANCE.classEntry(map(d.asSymbol()))));
@@ -260,7 +260,7 @@ public CodeTransform asCodeTransform() {
cob.localVariableType(c.slot(), c.name().stringValue(),
mapSignature(c.signatureSymbol()), c.startScope(), c.endScope());
case LoadConstantInstruction ldc ->
- cob.constantInstruction(ldc.opcode(),
+ cob.loadConstant(ldc.opcode(),
mapConstantValue(ldc.constantValue()));
case RuntimeVisibleTypeAnnotationsAttribute aa ->
cob.with(RuntimeVisibleTypeAnnotationsAttribute.of(
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeLocalsShifterImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeLocalsShifterImpl.java
index 9b301ccc822..a68225fbf27 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeLocalsShifterImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeLocalsShifterImpl.java
@@ -50,15 +50,15 @@ public CodeLocalsShifterImpl(int fixed) {
public void accept(CodeBuilder cob, CodeElement coe) {
switch (coe) {
case LoadInstruction li ->
- cob.loadInstruction(
+ cob.loadLocal(
li.typeKind(),
shift(cob, li.slot(), li.typeKind()));
case StoreInstruction si ->
- cob.storeInstruction(
+ cob.storeLocal(
si.typeKind(),
shift(cob, si.slot(), si.typeKind()));
case IncrementInstruction ii ->
- cob.incrementInstruction(
+ cob.iinc(
shift(cob, ii.slot(), TypeKind.IntType),
ii.constant());
case LocalVariable lv ->
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeRelabelerImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeRelabelerImpl.java
index 0e9bacd1cd9..f191cbf3c1f 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeRelabelerImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeRelabelerImpl.java
@@ -51,18 +51,18 @@ public Label relabel(Label label, CodeBuilder cob) {
public void accept(CodeBuilder cob, CodeElement coe) {
switch (coe) {
case BranchInstruction bi ->
- cob.branchInstruction(
+ cob.branch(
bi.opcode(),
relabel(bi.target(), cob));
case LookupSwitchInstruction lsi ->
- cob.lookupSwitchInstruction(
+ cob.lookupswitch(
relabel(lsi.defaultTarget(), cob),
lsi.cases().stream().map(c ->
SwitchCase.of(
c.caseValue(),
relabel(c.target(), cob))).toList());
case TableSwitchInstruction tsi ->
- cob.tableSwitchInstruction(
+ cob.tableswitch(
tsi.lowValue(),
tsi.highValue(),
relabel(tsi.defaultTarget(), cob),
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackCounter.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackCounter.java
index 688af262c70..0b52d4e1ea5 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackCounter.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackCounter.java
@@ -37,6 +37,8 @@
import java.util.Queue;
import static java.lang.classfile.ClassFile.*;
+import java.lang.constant.ClassDesc;
+import java.util.stream.Collectors;
public final class StackCounter {
@@ -45,6 +47,7 @@ private record Target(int bci, int stack) {}
static StackCounter of(DirectCodeBuilder dcb, BufWriterImpl buf) {
return new StackCounter(
dcb,
+ buf.thisClass().asSymbol(),
dcb.methodInfo.methodName().stringValue(),
dcb.methodInfo.methodTypeSymbol(),
(dcb.methodInfo.methodFlags() & ACC_STATIC) != 0,
@@ -56,8 +59,11 @@ static StackCounter of(DirectCodeBuilder dcb, BufWriterImpl buf) {
private int stack, maxStack, maxLocals, rets;
private final RawBytecodeHelper bcs;
+ private final ClassDesc thisClass;
private final String methodName;
private final MethodTypeDesc methodDesc;
+ private final boolean isStatic;
+ private final ByteBuffer bytecode;
private final SplitConstantPool cp;
private final Queue targets;
private final BitSet visited;
@@ -91,14 +97,18 @@ private boolean next() {
}
public StackCounter(LabelContext labelContext,
+ ClassDesc thisClass,
String methodName,
MethodTypeDesc methodDesc,
boolean isStatic,
ByteBuffer bytecode,
SplitConstantPool cp,
List handlers) {
+ this.thisClass = thisClass;
this.methodName = methodName;
this.methodDesc = methodDesc;
+ this.isStatic = isStatic;
+ this.bytecode = bytecode;
this.cp = cp;
targets = new ArrayDeque<>();
maxStack = stack = rets = 0;
@@ -247,24 +257,24 @@ public StackCounter(LabelContext labelContext,
int low = bcs.getInt(alignedBci + 4);
int high = bcs.getInt(alignedBci + 2 * 4);
if (low > high) {
- error("low must be less than or equal to high in tableswitch");
+ throw error("low must be less than or equal to high in tableswitch");
}
keys = high - low + 1;
if (keys < 0) {
- error("too many keys in tableswitch");
+ throw error("too many keys in tableswitch");
}
delta = 1;
} else {
keys = bcs.getInt(alignedBci + 4);
if (keys < 0) {
- error("number of keys in lookupswitch less than 0");
+ throw error("number of keys in lookupswitch less than 0");
}
delta = 2;
for (int i = 0; i < (keys - 1); i++) {
int this_key = bcs.getInt(alignedBci + (2 + 2 * i) * 4);
int next_key = bcs.getInt(alignedBci + (2 + 2 * i + 2) * 4);
if (this_key >= next_key) {
- error("Bad lookupswitch instruction");
+ throw error("Bad lookupswitch instruction");
}
}
}
@@ -326,7 +336,7 @@ public StackCounter(LabelContext labelContext,
next();
}
default ->
- error(String.format("Bad instruction: %02x", opcode));
+ throw error(String.format("Bad instruction: %02x", opcode));
}
}
}
@@ -360,15 +370,17 @@ private void processLdc(int index) {
case TAG_CONSTANTDYNAMIC ->
addStackSlot(((ConstantDynamicEntry)cp.entryByIndex(index)).typeKind().slotSize());
default ->
- error("CP entry #%d %s is not loadable constant".formatted(index, cp.entryByIndex(index).tag()));
+ throw error("CP entry #%d %s is not loadable constant".formatted(index, cp.entryByIndex(index).tag()));
}
}
- private void error(String msg) {
- throw new IllegalArgumentException("%s at bytecode offset %d of method %s(%s)".formatted(
+ private IllegalArgumentException error(String msg) {
+ var sb = new StringBuilder("%s at bytecode offset %d of method %s(%s)".formatted(
msg,
bcs.bci,
methodName,
- methodDesc.displayDescriptor()));
+ methodDesc.parameterList().stream().map(ClassDesc::displayName).collect(Collectors.joining(","))));
+ Util.dumpMethod(cp, thisClass, methodName, methodDesc, isStatic ? ACC_STATIC : 0, bytecode, sb::append);
+ return new IllegalArgumentException(sb.toString());
}
}
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java
index 9d4f898e5cd..81e6f341a13 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java
@@ -48,8 +48,6 @@
import java.lang.classfile.Label;
import java.lang.classfile.attribute.StackMapTableAttribute;
import java.lang.classfile.Attributes;
-import java.lang.classfile.components.ClassPrinter;
-import java.lang.classfile.attribute.CodeAttribute;
/**
* StackMapGenerator is responsible for stack map frames generation.
@@ -836,36 +834,7 @@ private IllegalArgumentException generatorError(String msg, int offset) {
offset,
methodName,
methodDesc.parameterList().stream().map(ClassDesc::displayName).collect(Collectors.joining(","))));
- //try to attach debug info about corrupted bytecode to the message
- try {
- var cc = ClassFile.of();
- var clm = cc.parse(cc.build(cp.classEntry(thisType.sym()), cp, clb ->
- clb.withMethod(methodName, methodDesc, isStatic ? ACC_STATIC : 0, mb ->
- ((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute(Attributes.CODE) {
- @Override
- public void writeBody(BufWriter b) {
- b.writeU2(-1);//max stack
- b.writeU2(-1);//max locals
- b.writeInt(bytecode.limit());
- b.writeBytes(bytecode.array(), 0, bytecode.limit());
- b.writeU2(0);//exception handlers
- b.writeU2(0);//attributes
- }
- }))));
- ClassPrinter.toYaml(clm.methods().get(0).code().get(), ClassPrinter.Verbosity.TRACE_ALL, sb::append);
- } catch (Error | Exception suppresed) {
- //fallback to bytecode hex dump
- bytecode.rewind();
- while (bytecode.position() < bytecode.limit()) {
- sb.append("%n%04x:".formatted(bytecode.position()));
- for (int i = 0; i < 16 && bytecode.position() < bytecode.limit(); i++) {
- sb.append(" %02x".formatted(bytecode.get()));
- }
- }
- var err = new IllegalArgumentException(sb.toString());
- err.addSuppressed(suppresed);
- return err;
- }
+ Util.dumpMethod(cp, thisType.sym(), methodName, methodDesc, isStatic ? ACC_STATIC : 0, bytecode, sb::append);
return new IllegalArgumentException(sb.toString());
}
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java
index 11e3328e775..7bff7e6f06d 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@
import java.lang.classfile.Attribute;
import java.lang.classfile.AttributeMapper;
+import java.lang.classfile.Attributes;
+import java.lang.classfile.BufWriter;
import java.lang.classfile.ClassFile;
import java.lang.classfile.Opcode;
import java.lang.classfile.constantpool.ClassEntry;
@@ -43,6 +45,11 @@
import jdk.internal.access.SharedSecrets;
import static java.lang.classfile.ClassFile.ACC_STATIC;
+import java.lang.classfile.attribute.CodeAttribute;
+import java.lang.classfile.components.ClassPrinter;
+import java.lang.classfile.constantpool.ConstantPoolBuilder;
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
/**
* Helper to create and manipulate type descriptors, where type descriptors are
@@ -193,4 +200,41 @@ public static boolean isDoubleSlot(ClassDesc desc) {
char ch = desc.descriptorString().charAt(0);
return ch == 'D' || ch == 'J';
}
+
+ public static void dumpMethod(SplitConstantPool cp,
+ ClassDesc cls,
+ String methodName,
+ MethodTypeDesc methodDesc,
+ int acc,
+ ByteBuffer bytecode,
+ Consumer dump) {
+
+ // try to dump debug info about corrupted bytecode
+ try {
+ var cc = ClassFile.of();
+ var clm = cc.parse(cc.build(cp.classEntry(cls), cp, clb ->
+ clb.withMethod(methodName, methodDesc, acc, mb ->
+ ((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute(Attributes.CODE) {
+ @Override
+ public void writeBody(BufWriter b) {
+ b.writeU2(-1);//max stack
+ b.writeU2(-1);//max locals
+ b.writeInt(bytecode.limit());
+ b.writeBytes(bytecode.array(), 0, bytecode.limit());
+ b.writeU2(0);//exception handlers
+ b.writeU2(0);//attributes
+ }
+ }))));
+ ClassPrinter.toYaml(clm.methods().get(0).code().get(), ClassPrinter.Verbosity.TRACE_ALL, dump);
+ } catch (Error | Exception _) {
+ // fallback to bytecode hex dump
+ bytecode.rewind();
+ while (bytecode.position() < bytecode.limit()) {
+ dump.accept("%n%04x:".formatted(bytecode.position()));
+ for (int i = 0; i < 16 && bytecode.position() < bytecode.limit(); i++) {
+ dump.accept(" %02x".formatted(bytecode.get()));
+ }
+ }
+ }
+ }
}
diff --git a/src/java.base/share/classes/jdk/internal/event/FileForceEvent.java b/src/java.base/share/classes/jdk/internal/event/FileForceEvent.java
new file mode 100644
index 00000000000..f6dec6c8a5e
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/event/FileForceEvent.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.event;
+
+/**
+ * A JFR event for forced updates written to files. This event is mirrored in
+ * {@code jdk.jfr.events.FileForceEvent } where the event annotations are
+ * provided. Some of the methods are replaced by generated
+ * methods when jfr is enabled. Note that the order of the arguments of the
+ * {@link #commit(long, long, String, boolean)} method
+ * must be the same as the order of the fields.
+ */
+public class FileForceEvent extends Event {
+
+ // THE ORDER OF THE FOLLOWING FIELDS IS IMPORTANT!
+ // The order must match the argument order of the generated commit method.
+ public String path;
+ public boolean metaData;
+
+ /**
+ * Helper method to offer the data needed to potentially commit an event.
+ * The duration of the operation is computed using the current
+ * timestamp and the given start time. If the duration is meets
+ * or exceeds the configured value (determined by calling the generated method
+ * {@link #shouldCommit(long)}), an event will be emitted by calling
+ * {@link #commit(long, long, String, boolean)}.
+ *
+ * @param start timestamp of the start of the operation
+ * @param path the full pathname of the file
+ * @param metaData true if the file metadata is updated
+ */
+ public static void offer(long start, String path, boolean metaData) {
+ long duration = timestamp() - start;
+ if (shouldCommit(duration)) {
+ commit(start, duration, path, metaData);
+ }
+ }
+
+ /**
+ * Actually commit an event. The implementation is generated automatically.
+ * The order of the fields must be the same as the parameters in this method.
+ *
+ * @param start timestamp of the start of the operation
+ * @param duration time in nanoseconds to complete the operation
+ * @param path the full pathname of the file
+ * @param metaData true if the file metadata is updated
+ */
+ public static void commit(long start, long duration, String path, boolean metaData) {
+ // Generated by JFR
+ }
+
+ /**
+ * Determine if an event should be emitted. The duration of the operation
+ * must exceed some threshold in order to commit the event. The implementation
+ * of this method is generated automatically if jfr is enabled.
+ *
+ * @param duration time in nanoseconds to complete the operation
+ * @return true if the event should be commited
+ */
+ public static boolean shouldCommit(long duration) {
+ // Generated by JFR
+ return false;
+ }
+
+ /**
+ * Determine if this kind of event is enabled. The implementation
+ * of this method is generated automatically if jfr is enabled.
+ *
+ * @return true if this type of event is enabled, false otherwise
+ */
+ public static boolean enabled() {
+ // Generated by JFR
+ return false;
+ }
+
+ /**
+ * Fetch the current timestamp in nanoseconds. This method is used
+ * to determine the start and end of an operation. The implementation
+ * of this method is generated automatically if jfr is enabled.
+ *
+ * @return the current timestamp value
+ */
+ public static long timestamp() {
+ // Generated by JFR
+ return 0L;
+ }
+}
diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java
index 500e312b2f3..3aca7243a36 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java
@@ -23,6 +23,13 @@
* questions.
*
*/
+
+/*
+ * ===========================================================================
+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
+ * ===========================================================================
+ */
+
package jdk.internal.foreign;
import jdk.internal.foreign.abi.fallback.FallbackLinker;
@@ -44,6 +51,7 @@ public enum CABI {
LINUX_PPC_64_LE,
LINUX_RISCV_64,
LINUX_S390,
+ ZOS_S390,
FALLBACK,
UNSUPPORTED;
@@ -93,6 +101,8 @@ private static CABI computeCurrent() {
} else if (arch.equals("s390x")) {
if (OperatingSystem.isLinux()) {
return LINUX_S390;
+ } else {
+ return ZOS_S390;
}
}
} else if (FallbackLinker.isSupported()) {
diff --git a/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java
index 8681aaadbdc..813085e4d6d 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java
@@ -145,7 +145,7 @@ public Boolean run() {
libLookup(libs -> libs.load(jdkLibraryPath("syslookup")));
@SuppressWarnings("restricted")
- MemorySegment funcs = fallbackLibLookup.find("funcs").orElseThrow()
+ MemorySegment funcs = fallbackLibLookup.findOrThrow("funcs")
.reinterpret(WindowsFallbackSymbols.LAYOUT.byteSize());
Function> fallbackLookup = name -> Optional.ofNullable(WindowsFallbackSymbols.valueOfOrNull(name))
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java
index 4f3baaa0e71..96572b6912e 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java
@@ -22,6 +22,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/*
+ * ===========================================================================
+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
+ * ===========================================================================
+ */
+
package jdk.internal.foreign.abi;
import jdk.internal.foreign.SystemLookup;
@@ -35,6 +42,7 @@
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
+import jdk.internal.foreign.abi.s390.zos.ZosS390Linker;
import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker;
import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker;
import jdk.internal.foreign.layout.AbstractLayout;
@@ -66,6 +74,7 @@ public abstract sealed class AbstractLinker implements Linker permits LinuxAArch
Windowsx64Linker, AixPPC64Linker,
LinuxPPC64Linker, LinuxPPC64leLinker,
LinuxRISCV64Linker, LinuxS390Linker,
+ ZosS390Linker,
FallbackLinker {
public interface UpcallStubFactory {
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java b/src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java
index a399b815ee6..7f5ef54bdca 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java
@@ -274,8 +274,8 @@ private void specialize() {
if (shouldAcquire(i)) {
int scopeLocal = cb.allocateLocal(ReferenceType);
initialScopeSlots[numScopes++] = scopeLocal;
- cb.constantInstruction(null);
- cb.storeInstruction(ReferenceType, scopeLocal); // need to initialize all scope locals here in case an exception occurs
+ cb.loadConstant(null);
+ cb.storeLocal(ReferenceType, scopeLocal); // need to initialize all scope locals here in case an exception occurs
}
}
scopeSlots = Arrays.copyOf(initialScopeSlots, numScopes); // fit to size
@@ -284,7 +284,7 @@ private void specialize() {
// create a Binding.Context for this call
if (callingSequence.allocationSize() != 0) {
- cb.constantInstruction(callingSequence.allocationSize());
+ cb.loadConstant(callingSequence.allocationSize());
cb.invokestatic(CD_SharedUtils, "newBoundedArena", MTD_NEW_BOUNDED_ARENA);
} else if (callingSequence.forUpcall() && needsSession()) {
cb.invokestatic(CD_SharedUtils, "newEmptyArena", MTD_NEW_EMPTY_ARENA);
@@ -292,7 +292,7 @@ private void specialize() {
cb.getstatic(CD_SharedUtils, "DUMMY_ARENA", CD_Arena);
}
contextIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, contextIdx);
+ cb.storeLocal(ReferenceType, contextIdx);
// in case the call needs a return buffer, allocate it here.
// for upcalls the VM wrapper stub allocates the buffer.
@@ -300,7 +300,7 @@ private void specialize() {
emitLoadInternalAllocator();
emitAllocateCall(callingSequence.returnBufferSize(), 1);
returnBufferIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, returnBufferIdx);
+ cb.storeLocal(ReferenceType, returnBufferIdx);
}
Label tryStart = cb.newLabel();
@@ -323,7 +323,7 @@ private void specialize() {
// for downcalls, recipes have an input value, which we set up here
if (callingSequence.needsReturnBuffer() && i == 0) {
assert returnBufferIdx != -1;
- cb.loadInstruction(ReferenceType, returnBufferIdx);
+ cb.loadLocal(ReferenceType, returnBufferIdx);
pushType(MemorySegment.class);
} else {
emitGetInput();
@@ -339,7 +339,7 @@ private void specialize() {
// return buffer ptr is wrapped in a MemorySegment above, but not passed to the leaf handle
popType(MemorySegment.class);
returnBufferIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, returnBufferIdx);
+ cb.storeLocal(ReferenceType, returnBufferIdx);
} else {
// for upcalls the recipe result is an argument to the leaf handle
emitSetOutput(typeStack.pop());
@@ -352,14 +352,14 @@ private void specialize() {
// load the leaf MethodHandle
if (callingSequence.forDowncall()) {
- cb.constantInstruction(CLASS_DATA_DESC);
+ cb.loadConstant(CLASS_DATA_DESC);
} else {
- cb.loadInstruction(ReferenceType, 0); // load target arg
+ cb.loadLocal(ReferenceType, 0); // load target arg
}
cb.checkcast(CD_MethodHandle);
// load all the leaf args
for (int i = 0; i < leafArgSlots.length; i++) {
- cb.loadInstruction(TypeKind.from(leafArgTypes.get(i)), leafArgSlots[i]);
+ cb.loadLocal(TypeKind.from(leafArgTypes.get(i)), leafArgSlots[i]);
}
// call leaf MH
cb.invokevirtual(CD_MethodHandle, "invokeExact", desc(leafType));
@@ -396,7 +396,7 @@ private void specialize() {
} else {
popType(callerMethodType.returnType());
assert typeStack.isEmpty();
- cb.returnInstruction(TypeKind.from(callerMethodType.returnType()));
+ cb.return_(TypeKind.from(callerMethodType.returnType()));
}
} else {
assert callerMethodType.returnType() == void.class;
@@ -411,13 +411,13 @@ private void specialize() {
// finally
emitCleanup();
if (callingSequence.forDowncall()) {
- cb.throwInstruction();
+ cb.athrow();
} else {
cb.invokestatic(CD_SharedUtils, "handleUncaughtException", MTD_HANDLE_UNCAUGHT_EXCEPTION);
if (callerMethodType.returnType() != void.class) {
TypeKind returnTypeKind = TypeKind.from(callerMethodType.returnType());
emitConstZero(returnTypeKind);
- cb.returnInstruction(returnTypeKind);
+ cb.return_(returnTypeKind);
} else {
cb.return_();
}
@@ -477,13 +477,13 @@ private void doBindings(List bindings) {
}
private void emitSetOutput(Class> storeType) {
- cb.storeInstruction(TypeKind.from(storeType), leafArgSlots[leafArgTypes.size()]);
+ cb.storeLocal(TypeKind.from(storeType), leafArgSlots[leafArgTypes.size()]);
leafArgTypes.add(storeType);
}
private void emitGetInput() {
Class> highLevelType = callerMethodType.parameterType(paramIndex);
- cb.loadInstruction(TypeKind.from(highLevelType), cb.parameterSlot(paramIndex));
+ cb.loadLocal(TypeKind.from(highLevelType), cb.parameterSlot(paramIndex));
if (shouldAcquire(paramIndex)) {
cb.dup();
@@ -505,7 +505,7 @@ private void emitAcquireScope() {
boolean hasOtherScopes = curScopeLocalIdx != 0;
for (int i = 0; i < curScopeLocalIdx; i++) {
cb.dup(); // dup for comparison
- cb.loadInstruction(ReferenceType, scopeSlots[i]);
+ cb.loadLocal(ReferenceType, scopeSlots[i]);
cb.if_acmpeq(skipAcquire);
}
@@ -514,7 +514,7 @@ private void emitAcquireScope() {
int nextScopeLocal = scopeSlots[curScopeLocalIdx++];
// call acquire first here. So that if it fails, we don't call release
cb.invokevirtual(CD_MemorySessionImpl, "acquire0", MTD_ACQUIRE0); // call acquire on the other
- cb.storeInstruction(ReferenceType, nextScopeLocal); // store off one to release later
+ cb.storeLocal(ReferenceType, nextScopeLocal); // store off one to release later
if (hasOtherScopes) { // avoid ASM generating a bunch of nops for the dead code
cb.goto_(end);
@@ -528,9 +528,9 @@ private void emitAcquireScope() {
private void emitReleaseScopes() {
for (int scopeLocal : scopeSlots) {
- cb.loadInstruction(ReferenceType, scopeLocal);
+ cb.loadLocal(ReferenceType, scopeLocal);
cb.ifThen(Opcode.IFNONNULL, ifCb -> {
- ifCb.loadInstruction(ReferenceType, scopeLocal);
+ ifCb.loadLocal(ReferenceType, scopeLocal);
ifCb.invokevirtual(CD_MemorySessionImpl, "release0", MTD_RELEASE0);
});
}
@@ -539,18 +539,18 @@ private void emitReleaseScopes() {
private void emitSaveReturnValue(Class> storeType) {
TypeKind typeKind = TypeKind.from(storeType);
retValIdx = cb.allocateLocal(typeKind);
- cb.storeInstruction(typeKind, retValIdx);
+ cb.storeLocal(typeKind, retValIdx);
}
private void emitRestoreReturnValue(Class> loadType) {
assert retValIdx != -1;
- cb.loadInstruction(TypeKind.from(loadType), retValIdx);
+ cb.loadLocal(TypeKind.from(loadType), retValIdx);
pushType(loadType);
}
private void emitLoadInternalSession() {
assert contextIdx != -1;
- cb.loadInstruction(ReferenceType, contextIdx);
+ cb.loadLocal(ReferenceType, contextIdx);
cb.checkcast(CD_Arena);
cb.invokeinterface(CD_Arena, "scope", MTD_SCOPE);
cb.checkcast(CD_MemorySessionImpl);
@@ -558,20 +558,20 @@ private void emitLoadInternalSession() {
private void emitLoadInternalAllocator() {
assert contextIdx != -1;
- cb.loadInstruction(ReferenceType, contextIdx);
+ cb.loadLocal(ReferenceType, contextIdx);
}
private void emitCloseContext() {
assert contextIdx != -1;
- cb.loadInstruction(ReferenceType, contextIdx);
+ cb.loadLocal(ReferenceType, contextIdx);
cb.checkcast(CD_Arena);
cb.invokeinterface(CD_Arena, "close", MTD_CLOSE);
}
private void emitBoxAddress(BoxAddress boxAddress) {
popType(long.class);
- cb.constantInstruction(boxAddress.size());
- cb.constantInstruction(boxAddress.align());
+ cb.loadConstant(boxAddress.size());
+ cb.loadConstant(boxAddress.align());
if (needsSession()) {
emitLoadInternalSession();
cb.invokestatic(CD_Utils, "longToAddress", MTD_LONG_TO_ADDRESS_SCOPE);
@@ -584,7 +584,7 @@ private void emitBoxAddress(BoxAddress boxAddress) {
private void emitAllocBuffer(Allocate binding) {
if (callingSequence.forDowncall()) {
assert returnAllocatorIdx != -1;
- cb.loadInstruction(ReferenceType, returnAllocatorIdx);
+ cb.loadLocal(ReferenceType, returnAllocatorIdx);
} else {
emitLoadInternalAllocator();
}
@@ -603,11 +603,11 @@ private void emitBufferStore(BufferStore bufferStore) {
if (SharedUtils.isPowerOfTwo(byteWidth)) {
int valueIdx = cb.allocateLocal(storeTypeKind);
- cb.storeInstruction(storeTypeKind, valueIdx);
+ cb.storeLocal(storeTypeKind, valueIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(storeType);
- cb.constantInstruction(offset);
- cb.loadInstruction(storeTypeKind, valueIdx);
+ cb.loadConstant(offset);
+ cb.loadLocal(storeTypeKind, valueIdx);
MethodTypeDesc descriptor = MethodTypeDesc.of(CD_void, valueLayoutType, CD_long, desc(storeType));
cb.invokeinterface(CD_MemorySegment, "set", descriptor);
} else {
@@ -618,9 +618,9 @@ private void emitBufferStore(BufferStore bufferStore) {
assert storeType == long.class; // chunking only for int and long
}
int longValueIdx = cb.allocateLocal(LongType);
- cb.storeInstruction(LongType, longValueIdx);
+ cb.storeLocal(LongType, longValueIdx);
int writeAddrIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, writeAddrIdx);
+ cb.storeLocal(ReferenceType, writeAddrIdx);
int remaining = byteWidth;
int chunkOffset = 0;
@@ -647,25 +647,25 @@ private void emitBufferStore(BufferStore bufferStore) {
//int writeChunk = (int) (((0xFFFF_FFFFL << shiftAmount) & longValue) >>> shiftAmount);
int shiftAmount = chunkOffset * Byte.SIZE;
mask = mask << shiftAmount;
- cb.loadInstruction(LongType, longValueIdx);
- cb.constantInstruction(mask);
+ cb.loadLocal(LongType, longValueIdx);
+ cb.loadConstant(mask);
cb.land();
if (shiftAmount != 0) {
- cb.constantInstruction(shiftAmount);
+ cb.loadConstant(shiftAmount);
cb.lushr();
}
cb.l2i();
TypeKind chunkStoreTypeKind = TypeKind.from(chunkStoreType);
int chunkIdx = cb.allocateLocal(chunkStoreTypeKind);
- cb.storeInstruction(chunkStoreTypeKind, chunkIdx);
+ cb.storeLocal(chunkStoreTypeKind, chunkIdx);
// chunk done, now write it
//writeAddress.set(JAVA_SHORT_UNALIGNED, offset, writeChunk);
- cb.loadInstruction(ReferenceType, writeAddrIdx);
+ cb.loadLocal(ReferenceType, writeAddrIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkStoreType);
long writeOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize);
- cb.constantInstruction(writeOffset);
- cb.loadInstruction(chunkStoreTypeKind, chunkIdx);
+ cb.loadConstant(writeOffset);
+ cb.loadLocal(chunkStoreTypeKind, chunkIdx);
MethodTypeDesc descriptor = MethodTypeDesc.of(CD_void, valueLayoutType, CD_long, desc(chunkStoreType));
cb.invokeinterface(CD_MemorySegment, "set", descriptor);
@@ -690,13 +690,13 @@ private void emitVMStore(VMStore vmStore) {
emitSaveReturnValue(storeType);
} else {
int valueIdx = cb.allocateLocal(storeTypeKind);
- cb.storeInstruction(storeTypeKind, valueIdx); // store away the stored value, need it later
+ cb.storeLocal(storeTypeKind, valueIdx); // store away the stored value, need it later
assert returnBufferIdx != -1;
- cb.loadInstruction(ReferenceType, returnBufferIdx);
+ cb.loadLocal(ReferenceType, returnBufferIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(storeType);
- cb.constantInstruction(retBufOffset);
- cb.loadInstruction(storeTypeKind, valueIdx);
+ cb.loadConstant(retBufOffset);
+ cb.loadLocal(storeTypeKind, valueIdx);
MethodTypeDesc descriptor = MethodTypeDesc.of(CD_void, valueLayoutType, CD_long, desc(storeType));
cb.invokeinterface(CD_MemorySegment, "set", descriptor);
retBufOffset += abi.arch.typeSize(vmStore.storage().type());
@@ -713,9 +713,9 @@ private void emitVMLoad(VMLoad vmLoad) {
emitRestoreReturnValue(loadType);
} else {
assert returnBufferIdx != -1;
- cb.loadInstruction(ReferenceType, returnBufferIdx);
+ cb.loadLocal(ReferenceType, returnBufferIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(loadType);
- cb.constantInstruction(retBufOffset);
+ cb.loadConstant(retBufOffset);
MethodTypeDesc descriptor = MethodTypeDesc.of(desc(loadType), valueLayoutType, CD_long);
cb.invokeinterface(CD_MemorySegment, "get", descriptor);
retBufOffset += abi.arch.typeSize(vmLoad.storage().type());
@@ -735,14 +735,14 @@ private void emitDupBinding() {
private void emitShiftLeft(ShiftLeft shiftLeft) {
popType(long.class);
- cb.constantInstruction(shiftLeft.shiftAmount() * Byte.SIZE);
+ cb.loadConstant(shiftLeft.shiftAmount() * Byte.SIZE);
cb.lshl();
pushType(long.class);
}
private void emitShiftRight(ShiftRight shiftRight) {
popType(long.class);
- cb.constantInstruction(shiftRight.shiftAmount() * Byte.SIZE);
+ cb.loadConstant(shiftRight.shiftAmount() * Byte.SIZE);
cb.lushr();
pushType(long.class);
}
@@ -757,7 +757,7 @@ private void emitCast(Cast cast) {
// implement least significant byte non-zero test
// select first byte
- cb.constantInstruction(0xFF);
+ cb.loadConstant(0xFF);
cb.iand();
// convert to boolean
@@ -808,17 +808,17 @@ private void emitBufferLoad(BufferLoad bufferLoad) {
if (SharedUtils.isPowerOfTwo(byteWidth)) {
ClassDesc valueLayoutType = emitLoadLayoutConstant(loadType);
- cb.constantInstruction(offset);
+ cb.loadConstant(offset);
MethodTypeDesc descriptor = MethodTypeDesc.of(desc(loadType), valueLayoutType, CD_long);
cb.invokeinterface(CD_MemorySegment, "get", descriptor);
} else {
// chunked
int readAddrIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, readAddrIdx);
+ cb.storeLocal(ReferenceType, readAddrIdx);
- cb.constantInstruction(0L); // result
+ cb.loadConstant(0L); // result
int resultIdx = cb.allocateLocal(LongType);
- cb.storeInstruction(LongType, resultIdx);
+ cb.storeLocal(LongType, resultIdx);
int remaining = byteWidth;
int chunkOffset = 0;
@@ -847,30 +847,30 @@ private void emitBufferLoad(BufferLoad bufferLoad) {
throw new IllegalStateException("Unexpected chunk size for chunked write: " + chunkSize);
}
// read from segment
- cb.loadInstruction(ReferenceType, readAddrIdx);
+ cb.loadLocal(ReferenceType, readAddrIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkType);
MethodTypeDesc descriptor = MethodTypeDesc.of(desc(chunkType), valueLayoutType, CD_long);
long readOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize);
- cb.constantInstruction(readOffset);
+ cb.loadConstant(readOffset);
cb.invokeinterface(CD_MemorySegment, "get", descriptor);
cb.invokestatic(toULongHolder, "toUnsignedLong", toULongDescriptor);
// shift to right offset
int shiftAmount = chunkOffset * Byte.SIZE;
if (shiftAmount != 0) {
- cb.constantInstruction(shiftAmount);
+ cb.loadConstant(shiftAmount);
cb.lshl();
}
// add to result
- cb.loadInstruction(LongType, resultIdx);
+ cb.loadLocal(LongType, resultIdx);
cb.lor();
- cb.storeInstruction(LongType, resultIdx);
+ cb.storeLocal(LongType, resultIdx);
remaining -= chunkSize;
chunkOffset += chunkSize;
} while (remaining != 0);
- cb.loadInstruction(LongType, resultIdx);
+ cb.loadLocal(LongType, resultIdx);
if (loadType == int.class) {
cb.l2i();
} else {
@@ -890,25 +890,25 @@ private void emitCopyBuffer(Copy copy) {
// operand/srcSegment is on the stack
// generating a call to:
// MemorySegment::copy(MemorySegment srcSegment, long srcOffset, MemorySegment dstSegment, long dstOffset, long bytes)
- cb.constantInstruction(0L);
+ cb.loadConstant(0L);
// create the dstSegment by allocating it. Similar to:
// context.allocator().allocate(size, alignment)
emitLoadInternalAllocator();
emitAllocateCall(size, alignment);
cb.dup();
int storeIdx = cb.allocateLocal(ReferenceType);
- cb.storeInstruction(ReferenceType, storeIdx);
- cb.constantInstruction(0L);
- cb.constantInstruction(size);
+ cb.storeLocal(ReferenceType, storeIdx);
+ cb.loadConstant(0L);
+ cb.loadConstant(size);
cb.invokestatic(CD_MemorySegment, "copy", MTD_COPY, true);
- cb.loadInstruction(ReferenceType, storeIdx);
+ cb.loadLocal(ReferenceType, storeIdx);
pushType(MemorySegment.class);
}
private void emitAllocateCall(long size, long alignment) {
- cb.constantInstruction(size);
- cb.constantInstruction(alignment);
+ cb.loadConstant(size);
+ cb.loadConstant(alignment);
cb.invokeinterface(CD_SegmentAllocator, "allocate", MTD_ALLOCATE);
}
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java
index 83698398eda..8088e414f7a 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java
@@ -22,6 +22,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/*
+ * ===========================================================================
+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
+ * ===========================================================================
+ */
+
package jdk.internal.foreign.abi;
import jdk.internal.access.JavaLangAccess;
@@ -38,6 +45,7 @@
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
+import jdk.internal.foreign.abi.s390.zos.ZosS390Linker;
import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker;
import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker;
import jdk.internal.vm.annotation.ForceInline;
@@ -251,6 +259,7 @@ public static Linker getSystemLinker() {
case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance();
case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance();
case LINUX_S390 -> LinuxS390Linker.getInstance();
+ case ZOS_S390 -> ZosS390Linker.getInstance();
case FALLBACK -> FallbackLinker.getInstance();
case UNSUPPORTED -> throw new UnsupportedOperationException("Platform does not support native linker");
};
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390CallArranger.java
new file mode 100644
index 00000000000..a529a3c821f
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390CallArranger.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * ===========================================================================
+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
+ * ===========================================================================
+ */
+
+package jdk.internal.foreign.abi.s390.zos;
+
+import java.lang.foreign.FunctionDescriptor;
+import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
+import jdk.internal.foreign.abi.DowncallLinker;
+import jdk.internal.foreign.abi.LinkerOptions;
+import jdk.internal.foreign.abi.UpcallLinker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+/**
+ * For the s390 C ABI specifically, this class uses the DowncallLinker API
+ * which is turned into a MethodHandle to invoke the native code.
+ */
+public class ZosS390CallArranger {
+
+ /* Replace DowncallLinker in OpenJDK with the implementation of DowncallLinker specific to OpenJ9. */
+ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) {
+ return DowncallLinker.getBoundMethodHandle(mt, cDesc, options);
+ }
+
+ /* Replace UpcallLinker in OpenJDK with the implementation of UpcallLinker specific to OpenJ9. */
+ public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) {
+ return UpcallLinker.makeFactory(mt, cDesc, options);
+ }
+}
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390Linker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390Linker.java
new file mode 100644
index 00000000000..07f72f3a940
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/zos/ZosS390Linker.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * ===========================================================================
+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
+ * ===========================================================================
+ */
+
+package jdk.internal.foreign.abi.s390.zos;
+
+import jdk.internal.foreign.abi.AbstractLinker;
+import jdk.internal.foreign.abi.LinkerOptions;
+import jdk.internal.foreign.abi.SharedUtils;
+
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.ValueLayout;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.Map;
+
+public final class ZosS390Linker extends AbstractLinker {
+
+ private static final Map CANONICAL_LAYOUTS =
+ SharedUtils.canonicalLayouts(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT);
+
+ public static ZosS390Linker getInstance() {
+ final class Holder {
+ private static final ZosS390Linker INSTANCE = new ZosS390Linker();
+ }
+
+ return Holder.INSTANCE;
+ }
+
+ private ZosS390Linker() {
+ // Ensure there is only one instance
+ }
+
+ @Override
+ protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) {
+ return ZosS390CallArranger.arrangeDowncall(inferredMethodType, function, options);
+ }
+
+ @Override
+ protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function, LinkerOptions options) {
+ return ZosS390CallArranger.arrangeUpcall(targetType, function, options);
+ }
+
+ @Override
+ public Map canonicalLayouts() {
+ return CANONICAL_LAYOUTS;
+ }
+}
diff --git a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java
index 1fa93390215..cd87db30d7f 100644
--- a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java
+++ b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java
@@ -23,7 +23,7 @@
* questions.
*/
-/**
+/*
*******************************************************************************
* Copyright (C) 1996-2014, International Business Machines Corporation and
* others. All Rights Reserved.
diff --git a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java
index cdfdef9fbf9..bfeb0b7e621 100644
--- a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java
+++ b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java
@@ -2409,9 +2409,9 @@ else if (dirProp == PDI) {
return directionFromFlags();
}
- /*********************************************************************/
+ /* *******************************************************************/
/* The Properties state machine table */
- /*********************************************************************/
+ /* *******************************************************************/
/* */
/* All table cells are 8 bits: */
/* bits 0..4: next state */
@@ -2422,9 +2422,9 @@ else if (dirProp == PDI) {
/* Cells may also be of format "_(x,y)" where x represents an action */
/* to perform and y represents the next state. */
/* */
- /*********************************************************************/
+ /* *******************************************************************/
/* Definitions and type for properties state tables */
- /*********************************************************************/
+ /* *******************************************************************/
private static final int IMPTABPROPS_COLUMNS = 16;
private static final int IMPTABPROPS_RES = IMPTABPROPS_COLUMNS - 1;
private static short GetStateProps(short cell) {
@@ -2447,7 +2447,7 @@ private static short GetActionProps(short cell) {
private static final short _S = 5;
private static final short _B = 6; /* reduced dirProp */
- /*********************************************************************/
+ /* *******************************************************************/
/* */
/* PROPERTIES STATE TABLE */
/* */
@@ -2510,9 +2510,9 @@ private static short GetActionProps(short cell) {
/*23 ENR+ET */ { 32+1, 32+2, 21, 32+5, 32+7, 32+15, 32+17, 32+7, 23, 32+7, 23, 23, 32+3, 18, 21, _AN }
};
- /*********************************************************************/
+ /* *******************************************************************/
/* The levels state machine tables */
- /*********************************************************************/
+ /* *******************************************************************/
/* */
/* All table cells are 8 bits: */
/* bits 0..3: next state */
@@ -2525,9 +2525,9 @@ private static short GetActionProps(short cell) {
/* */
/* This format limits each table to 16 states each and to 15 actions.*/
/* */
- /*********************************************************************/
+ /* *******************************************************************/
/* Definitions and type for levels state tables */
- /*********************************************************************/
+ /* *******************************************************************/
private static final int IMPTABLEVELS_COLUMNS = _B + 2;
private static final int IMPTABLEVELS_RES = IMPTABLEVELS_COLUMNS - 1;
private static short GetState(byte cell) { return (short)(cell & 0x0f); }
@@ -2544,7 +2544,7 @@ private static class ImpTabPair {
}
}
- /*********************************************************************/
+ /* *******************************************************************/
/* */
/* LEVELS STATE TABLES */
/* */
diff --git a/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java b/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java
index 4205487a966..e84e1d4c0d4 100644
--- a/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java
+++ b/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java
@@ -22,7 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-/**
+/*
*******************************************************************************
* Copyright (C) 1996-2014, International Business Machines Corporation and
* others. All Rights Reserved.
diff --git a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java
index 228aaf6ea7d..c17f570a3ef 100644
--- a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java
+++ b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java
@@ -82,7 +82,7 @@ public enum Feature {
STRUCTURED_CONCURRENCY,
@JEP(number=466, title="ClassFile API", status="Second Preview")
CLASSFILE_API,
- @JEP(number=461, title="Stream Gatherers", status="Preview")
+ @JEP(number=473, title="Stream Gatherers", status="Second Preview")
STREAM_GATHERERS,
LANGUAGE_MODEL,
/**
diff --git a/src/java.base/share/classes/jdk/internal/misc/Blocker.java b/src/java.base/share/classes/jdk/internal/misc/Blocker.java
index e427d9520d5..d41ae73709f 100644
--- a/src/java.base/share/classes/jdk/internal/misc/Blocker.java
+++ b/src/java.base/share/classes/jdk/internal/misc/Blocker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,20 +25,18 @@
package jdk.internal.misc;
-import java.util.concurrent.ForkJoinPool;
import jdk.internal.access.JavaLangAccess;
-import jdk.internal.access.JavaUtilConcurrentFJPAccess;
import jdk.internal.access.SharedSecrets;
/**
* Defines static methods to mark the beginning and end of a possibly blocking
* operation. The methods are intended to be used with try-finally as follows:
* {@snippet lang=java :
- * long comp = Blocker.begin();
+ * boolean attempted = Blocker.begin();
* try {
* // blocking operation
* } finally {
- * Blocker.end(comp);
+ * Blocker.end(attempted);
* }
* }
* If invoked from a virtual thread and the underlying carrier thread is a
@@ -62,64 +60,35 @@ private static Thread currentCarrierThread() {
}
/**
- * Marks the beginning of a possibly blocking operation.
- * @return the return value from the attempt to compensate or -1 if not attempted
+ * Marks the beginning of a blocking operation.
+ * @return true if tryCompensate attempted
*/
- public static long begin() {
+ public static boolean begin() {
if (VM.isBooted()
- && currentCarrierThread() instanceof CarrierThread ct && !ct.inBlocking()) {
- ct.beginBlocking();
- boolean completed = false;
- try {
- long comp = ForkJoinPools.beginCompensatedBlock(ct.getPool());
- assert currentCarrierThread() == ct;
- completed = true;
- return comp;
- } finally {
- if (!completed) {
- ct.endBlocking();
- }
- }
+ && Thread.currentThread().isVirtual()
+ && currentCarrierThread() instanceof CarrierThread ct) {
+ return ct.beginBlocking();
}
- return -1;
+ return false;
}
/**
* Marks the beginning of a possibly blocking operation.
* @param blocking true if the operation may block, otherwise false
- * @return the return value from the attempt to compensate, -1 if not attempted
- * or blocking is false
+ * @return true if tryCompensate attempted
*/
- public static long begin(boolean blocking) {
- return (blocking) ? begin() : -1;
+ public static boolean begin(boolean blocking) {
+ return (blocking) ? begin() : false;
}
/**
* Marks the end of an operation that may have blocked.
- * @param compensateReturn the value returned by the begin method
+ * @param attempted if tryCompensate attempted
*/
- public static void end(long compensateReturn) {
- if (compensateReturn >= 0) {
- assert currentCarrierThread() instanceof CarrierThread ct && ct.inBlocking();
+ public static void end(boolean attempted) {
+ if (attempted) {
CarrierThread ct = (CarrierThread) currentCarrierThread();
- ForkJoinPools.endCompensatedBlock(ct.getPool(), compensateReturn);
ct.endBlocking();
}
}
-
- /**
- * Defines static methods to invoke non-public ForkJoinPool methods via the
- * shared secret support.
- */
- private static class ForkJoinPools {
- private static final JavaUtilConcurrentFJPAccess FJP_ACCESS =
- SharedSecrets.getJavaUtilConcurrentFJPAccess();
- static long beginCompensatedBlock(ForkJoinPool pool) {
- return FJP_ACCESS.beginCompensatedBlock(pool);
- }
- static void endCompensatedBlock(ForkJoinPool pool, long post) {
- FJP_ACCESS.endCompensatedBlock(pool, post);
- }
- }
-
}
diff --git a/src/java.base/share/classes/jdk/internal/misc/CarrierThread.java b/src/java.base/share/classes/jdk/internal/misc/CarrierThread.java
index e4276d4904e..d20b402fe92 100644
--- a/src/java.base/share/classes/jdk/internal/misc/CarrierThread.java
+++ b/src/java.base/share/classes/jdk/internal/misc/CarrierThread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,9 @@
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import jdk.internal.access.JavaLangAccess;
+import jdk.internal.access.JavaUtilConcurrentFJPAccess;
import jdk.internal.access.SharedSecrets;
+import jdk.internal.vm.Continuation;
/**
* A ForkJoinWorkerThread that can be used as a carrier thread.
@@ -49,7 +51,14 @@ public class CarrierThread extends ForkJoinWorkerThread {
private static final long INHERITABLETHREADLOCALS;
private static final long INHERITEDACCESSCONTROLCONTEXT;
- private boolean blocking; // true if in blocking op
+ // compensating state
+ private static final int NOT_COMPENSATING = 0;
+ private static final int COMPENSATE_IN_PROGRESS = 1;
+ private static final int COMPENSATING = 2;
+ private int compensating;
+
+ // FJP value to adjust release counts
+ private long compensateValue;
@SuppressWarnings("this-escape")
public CarrierThread(ForkJoinPool pool) {
@@ -60,27 +69,44 @@ public CarrierThread(ForkJoinPool pool) {
}
/**
- * For use by {@link Blocker} to test if the thread is in a blocking operation.
+ * Mark the start of a blocking operation.
*/
- boolean inBlocking() {
- //assert JLA.currentCarrierThread() == this;
- return blocking;
- }
+ public boolean beginBlocking() {
+ assert Thread.currentThread().isVirtual() && JLA.currentCarrierThread() == this;
+ assert compensating == NOT_COMPENSATING || compensating == COMPENSATING;
- /**
- * For use by {@link Blocker} to mark the start of a blocking operation.
- */
- void beginBlocking() {
- //assert JLA.currentCarrierThread() == this && !blocking;
- blocking = true;
+ if (compensating == NOT_COMPENSATING) {
+ // don't preempt when attempting to compensate
+ Continuation.pin();
+ try {
+ compensating = COMPENSATE_IN_PROGRESS;
+
+ // Uses FJP.tryCompensate to start or re-activate a spare thread
+ compensateValue = ForkJoinPools.beginCompensatedBlock(getPool());
+ compensating = COMPENSATING;
+ return true;
+ } catch (Throwable e) {
+ // exception starting spare thread
+ compensating = NOT_COMPENSATING;
+ throw e;
+ } finally {
+ Continuation.unpin();
+ }
+ } else {
+ return false;
+ }
}
/**
- * For use by {@link Blocker} to mark the end of a blocking operation.
+ * Mark the end of a blocking operation.
*/
- void endBlocking() {
- //assert JLA.currentCarrierThread() == this && blocking;
- blocking = false;
+ public void endBlocking() {
+ assert Thread.currentThread() == this || JLA.currentCarrierThread() == this;
+ if (compensating == COMPENSATING) {
+ ForkJoinPools.endCompensatedBlock(getPool(), compensateValue);
+ compensating = NOT_COMPENSATING;
+ compensateValue = 0;
+ }
}
@Override
@@ -95,7 +121,7 @@ public void setContextClassLoader(ClassLoader cl) {
* The thread group for the carrier threads.
*/
@SuppressWarnings("removal")
- private static final ThreadGroup carrierThreadGroup() {
+ private static ThreadGroup carrierThreadGroup() {
return AccessController.doPrivileged(new PrivilegedAction() {
public ThreadGroup run() {
ThreadGroup group = JLA.currentCarrierThread().getThreadGroup();
@@ -117,6 +143,21 @@ private static AccessControlContext innocuousACC() {
});
}
+ /**
+ * Defines static methods to invoke non-public ForkJoinPool methods via the
+ * shared secret support.
+ */
+ private static class ForkJoinPools {
+ private static final JavaUtilConcurrentFJPAccess FJP_ACCESS =
+ SharedSecrets.getJavaUtilConcurrentFJPAccess();
+ static long beginCompensatedBlock(ForkJoinPool pool) {
+ return FJP_ACCESS.beginCompensatedBlock(pool);
+ }
+ static void endCompensatedBlock(ForkJoinPool pool, long post) {
+ FJP_ACCESS.endCompensatedBlock(pool, post);
+ }
+ }
+
static {
CONTEXTCLASSLOADER = U.objectFieldOffset(Thread.class,
"contextClassLoader");
diff --git a/src/java.base/share/classes/jdk/internal/platform/Metrics.java b/src/java.base/share/classes/jdk/internal/platform/Metrics.java
index c45e3e52257..50523d137ef 100644
--- a/src/java.base/share/classes/jdk/internal/platform/Metrics.java
+++ b/src/java.base/share/classes/jdk/internal/platform/Metrics.java
@@ -72,7 +72,7 @@ public static Metrics systemMetrics() {
public String getProvider();
- /*****************************************************************
+ /* ***************************************************************
* CPU Accounting Subsystem
****************************************************************/
@@ -123,7 +123,7 @@ public static Metrics systemMetrics() {
*/
public long getCpuSystemUsage();
- /*****************************************************************
+ /* ***************************************************************
* CPU Scheduling Metrics
****************************************************************/
@@ -215,7 +215,7 @@ public static Metrics systemMetrics() {
*/
public long getEffectiveCpuCount();
- /*****************************************************************
+ /* ***************************************************************
* CPU Sets
****************************************************************/
@@ -271,7 +271,7 @@ public static Metrics systemMetrics() {
*/
public int[] getEffectiveCpuSetMems();
- /*****************************************************************
+ /* ***************************************************************
* Memory Subsystem
****************************************************************/
@@ -352,7 +352,7 @@ public static Metrics systemMetrics() {
*/
public long getMemorySoftLimit();
- /*****************************************************************
+ /* ***************************************************************
* pids subsystem
****************************************************************/
@@ -373,7 +373,7 @@ public static Metrics systemMetrics() {
*/
public long getPidsCurrent();
- /*****************************************************************
+ /* ***************************************************************
* BlKIO Subsystem
****************************************************************/
diff --git a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java
index 61be28519fc..8f8ea651d65 100644
--- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java
+++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -200,7 +200,7 @@ public static int vectorizedMismatch(Object a, long aOffset,
public static int vectorizedHashCode(Object array, int fromIndex, int length, int initialValue,
int basicType) {
return switch (basicType) {
- case T_BOOLEAN -> signedHashCode(initialValue, (byte[]) array, fromIndex, length);
+ case T_BOOLEAN -> unsignedHashCode(initialValue, (byte[]) array, fromIndex, length);
case T_CHAR -> array instanceof byte[]
? utf16hashCode(initialValue, (byte[]) array, fromIndex, length)
: hashCode(initialValue, (char[]) array, fromIndex, length);
@@ -211,7 +211,7 @@ public static int vectorizedHashCode(Object array, int fromIndex, int length, in
};
}
- private static int signedHashCode(int result, byte[] a, int fromIndex, int length) {
+ private static int unsignedHashCode(int result, byte[] a, int fromIndex, int length) {
int end = fromIndex + length;
for (int i = fromIndex; i < end; i++) {
result = 31 * result + (a[i] & 0xff);
diff --git a/src/java.base/share/classes/jdk/internal/vm/StackChunk.java b/src/java.base/share/classes/jdk/internal/vm/StackChunk.java
index 0c48ce67934..ab562706c24 100644
--- a/src/java.base/share/classes/jdk/internal/vm/StackChunk.java
+++ b/src/java.base/share/classes/jdk/internal/vm/StackChunk.java
@@ -31,10 +31,10 @@ public static void init() {}
private StackChunk parent;
private int size; // in words
private int sp; // in words
- private int argsize; // bottom stack-passed arguments, in words
+ private int bottom; // in words
// The stack itself is appended here by the VM, as well as some injected fields
public StackChunk parent() { return parent; }
- public boolean isEmpty() { return sp >= (size - argsize); }
+ public boolean isEmpty() { return sp == bottom; }
}
diff --git a/src/java.base/share/classes/sun/invoke/util/Wrapper.java b/src/java.base/share/classes/sun/invoke/util/Wrapper.java
index 76aede09487..fef9192932d 100644
--- a/src/java.base/share/classes/sun/invoke/util/Wrapper.java
+++ b/src/java.base/share/classes/sun/invoke/util/Wrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,25 +25,27 @@
package sun.invoke.util;
-import java.util.Map;
import static sun.invoke.util.Wrapper.NumericClasses.*;
import jdk.internal.vm.annotation.DontInline;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDescs;
+
public enum Wrapper {
- // wrapperType simple primitiveType simple char emptyArray format numericClass superClass
- BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0], Format.unsigned( 1), 0, 0),
+ // wrapperType simple primitiveType simple char emptyArray format numericClass superClass classDescriptor
+ BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0], Format.unsigned( 1), 0, 0, ConstantDescs.CD_boolean),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
// Avoid boxing integral types here to defer initialization of internal caches
- BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8), BYTE_CLASS, BYTE_SUPERCLASSES),
- SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16), SHORT_CLASS, SHORT_SUPERCLASSES),
- CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16), CHAR_CLASS, CHAR_SUPERCLASSES),
- INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32), INT_CLASS, INT_SUPERCLASSES),
- LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64), LONG_CLASS, LONG_SUPERCLASSES),
- FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32), FLOAT_CLASS, FLOAT_SUPERCLASSES),
- DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64), DOUBLE_CLASS, DOUBLE_CLASS),
- OBJECT ( Object.class, "Object", Object.class, "Object", 'L', new Object[0], Format.other( 1), 0, 0),
+ BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8), BYTE_CLASS, BYTE_SUPERCLASSES, ConstantDescs.CD_byte),
+ SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16), SHORT_CLASS, SHORT_SUPERCLASSES, ConstantDescs.CD_short),
+ CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16), CHAR_CLASS, CHAR_SUPERCLASSES, ConstantDescs.CD_char),
+ INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32), INT_CLASS, INT_SUPERCLASSES, ConstantDescs.CD_int),
+ LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64), LONG_CLASS, LONG_SUPERCLASSES, ConstantDescs.CD_long),
+ FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32), FLOAT_CLASS, FLOAT_SUPERCLASSES, ConstantDescs.CD_float),
+ DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64), DOUBLE_CLASS, DOUBLE_CLASS, ConstantDescs.CD_double),
+ OBJECT ( Object.class, "Object", Object.class, "Object", 'L', new Object[0], Format.other( 1), 0, 0, ConstantDescs.CD_Object),
// VOID must be the last type, since it is "assignable" from any other type:
- VOID ( Void.class, "Void", void.class, "void", 'V', null, Format.other( 0), 0, 0),
+ VOID ( Void.class, "Void", void.class, "void", 'V', null, Format.other( 0), 0, 0, ConstantDescs.CD_void),
;
public static final int COUNT = 10;
@@ -58,8 +60,18 @@ public enum Wrapper {
private final int superClasses;
private final String wrapperSimpleName;
private final String primitiveSimpleName;
-
- private Wrapper(Class> wtype, String wtypeName, Class> ptype, String ptypeName, char tchar, Object emptyArray, int format, int numericClass, int superClasses) {
+ private final ClassDesc classDesc;
+
+ private Wrapper(Class> wtype,
+ String wtypeName,
+ Class> ptype,
+ String ptypeName,
+ char tchar,
+ Object emptyArray,
+ int format,
+ int numericClass,
+ int superClasses,
+ ClassDesc classDesc) {
this.wrapperType = wtype;
this.primitiveType = ptype;
this.basicTypeChar = tchar;
@@ -70,6 +82,7 @@ private Wrapper(Class> wtype, String wtypeName, Class> ptype, String ptypeNa
this.superClasses = superClasses;
this.wrapperSimpleName = wtypeName;
this.primitiveSimpleName = ptypeName;
+ this.classDesc = classDesc;
}
/** For debugging, give the details of this wrapper. */
@@ -376,6 +389,9 @@ public static Wrapper forBasicType(Class> type) {
}
}
+ /** A nominal descriptor of the wrapped type */
+ public ClassDesc classDescriptor() { return classDesc; }
+
/** What is the primitive type wrapped by this wrapper? */
public Class> primitiveType() { return primitiveType; }
diff --git a/src/java.base/share/classes/sun/net/www/content/text/plain.java b/src/java.base/share/classes/sun/net/www/content/text/plain.java
index 32836559756..33a9032b2bc 100644
--- a/src/java.base/share/classes/sun/net/www/content/text/plain.java
+++ b/src/java.base/share/classes/sun/net/www/content/text/plain.java
@@ -23,15 +23,15 @@
* questions.
*/
-/**
- * Plain text file handler.
- * @author Steven B. Byrne
- */
package sun.net.www.content.text;
import java.net.*;
import java.io.InputStream;
import java.io.IOException;
+/**
+ * Plain text file handler.
+ * @author Steven B. Byrne
+ */
public class plain extends ContentHandler {
/**
* Returns a PlainTextInputStream object from which data
diff --git a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java
index 6c601793c49..153de588938 100644
--- a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java
+++ b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -389,9 +389,9 @@ public KeepAliveKey(URL url, Object obj) {
*/
@Override
public boolean equals(Object obj) {
- if ((obj instanceof KeepAliveKey) == false)
+ if (!(obj instanceof KeepAliveKey kae))
return false;
- KeepAliveKey kae = (KeepAliveKey)obj;
+
return host.equals(kae.host)
&& (port == kae.port)
&& protocol.equals(kae.protocol)
@@ -405,7 +405,7 @@ public boolean equals(Object obj) {
@Override
public int hashCode() {
String str = protocol+host+port;
- return this.obj == null? str.hashCode() :
+ return this.obj == null ? str.hashCode() :
str.hashCode() + this.obj.hashCode();
}
}
diff --git a/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java
index a27a6137a37..16fb1d2ea6c 100644
--- a/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java
+++ b/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java
@@ -23,12 +23,6 @@
* questions.
*/
-/**
- * Open an file input stream given a URL.
- * @author James Gosling
- * @author Steven B. Byrne
- */
-
package sun.net.www.protocol.file;
import java.net.URL;
@@ -40,6 +34,11 @@
import java.util.*;
import java.text.SimpleDateFormat;
+/**
+ * Open a file input stream given a URL.
+ * @author James Gosling
+ * @author Steven B. Byrne
+ */
public class FileURLConnection extends URLConnection {
private static final String CONTENT_LENGTH = "content-length";
diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java
index ff54e474b8e..39d05b6e0e4 100644
--- a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java
+++ b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -65,7 +65,7 @@ protected AbstractDelegateHttpsURLConnection(URL url, Proxy p,
protected abstract javax.net.ssl.HostnameVerifier getHostnameVerifier();
- /**
+ /*
* No user application is able to call these routines, as no one
* should ever get access to an instance of
* DelegateHttpsURLConnection (sun.* or com.*)
diff --git a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
index 636230d8f38..0b72ee6a7c2 100644
--- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
+++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
@@ -50,6 +50,7 @@
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
+import jdk.internal.event.FileForceEvent;
import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.SegmentFactories;
import jdk.internal.misc.Blocker;
@@ -78,6 +79,7 @@ public class FileChannelImpl
// File access mode (immutable)
private final boolean writable;
private final boolean readable;
+ private final boolean sync; // O_SYNC or O_DSYNC
// Required to prevent finalization of creating stream (immutable)
private final Closeable parent;
@@ -122,12 +124,14 @@ public void run() {
}
private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
- boolean writable, boolean direct, Closeable parent)
+ boolean writable, boolean sync, boolean direct,
+ Closeable parent)
{
this.fd = fd;
this.path = path;
this.readable = readable;
this.writable = writable;
+ this.sync = sync;
this.direct = direct;
this.parent = parent;
if (direct) {
@@ -150,9 +154,9 @@ private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
// and RandomAccessFile::getChannel
public static FileChannel open(FileDescriptor fd, String path,
boolean readable, boolean writable,
- boolean direct, Closeable parent)
+ boolean sync, boolean direct, Closeable parent)
{
- return new FileChannelImpl(fd, path, readable, writable, direct, parent);
+ return new FileChannelImpl(fd, path, readable, writable, sync, direct, parent);
}
private void ensureOpen() throws IOException {
@@ -230,11 +234,11 @@ public int read(ByteBuffer dst) throws IOException {
if (!isOpen())
return 0;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(direct);
try {
n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
@@ -265,11 +269,11 @@ public long read(ByteBuffer[] dsts, int offset, int length)
if (!isOpen())
return 0;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(direct);
try {
n = IOUtil.read(fd, dsts, offset, length, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -298,11 +302,11 @@ public int write(ByteBuffer src) throws IOException {
if (!isOpen())
return 0;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(sync || direct);
try {
n = IOUtil.write(fd, src, -1, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -334,11 +338,11 @@ public long write(ByteBuffer[] srcs, int offset, int length)
if (!isOpen())
return 0;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(sync || direct);
try {
n = IOUtil.write(fd, srcs, offset, length, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
@@ -365,13 +369,8 @@ public long position() throws IOException {
return 0;
boolean append = fdAccess.getAppend(fd);
do {
- long comp = Blocker.begin();
- try {
- // in append-mode then position is advanced to end before writing
- p = (append) ? nd.size(fd) : nd.seek(fd, -1);
- } finally {
- Blocker.end(comp);
- }
+ // in append-mode then position is advanced to end before writing
+ p = (append) ? nd.size(fd) : nd.seek(fd, -1);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(p);
} finally {
@@ -396,12 +395,7 @@ public FileChannel position(long newPosition) throws IOException {
if (!isOpen())
return null;
do {
- long comp = Blocker.begin();
- try {
- p = nd.seek(fd, newPosition);
- } finally {
- Blocker.end(comp);
- }
+ p = nd.seek(fd, newPosition);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
return this;
} finally {
@@ -424,12 +418,7 @@ public long size() throws IOException {
if (!isOpen())
return -1;
do {
- long comp = Blocker.begin();
- try {
- s = nd.size(fd);
- } finally {
- Blocker.end(comp);
- }
+ s = nd.size(fd);
} while ((s == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(s);
} finally {
@@ -461,24 +450,14 @@ public FileChannel truncate(long newSize) throws IOException {
// get current size
long size;
do {
- long comp = Blocker.begin();
- try {
- size = nd.size(fd);
- } finally {
- Blocker.end(comp);
- }
+ size = nd.size(fd);
} while ((size == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
// get current position
do {
- long comp = Blocker.begin();
- try {
- p = nd.seek(fd, -1);
- } finally {
- Blocker.end(comp);
- }
+ p = nd.seek(fd, -1);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -487,12 +466,7 @@ public FileChannel truncate(long newSize) throws IOException {
// truncate file if given size is less than the current size
if (newSize < size) {
do {
- long comp = Blocker.begin();
- try {
- rv = nd.truncate(fd, newSize);
- } finally {
- Blocker.end(comp);
- }
+ rv = nd.truncate(fd, newSize);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -502,12 +476,7 @@ public FileChannel truncate(long newSize) throws IOException {
if (p > newSize)
p = newSize;
do {
- long comp = Blocker.begin();
- try {
- rp = nd.seek(fd, p);
- } finally {
- Blocker.end(comp);
- }
+ rp = nd.seek(fd, p);
} while ((rp == IOStatus.INTERRUPTED) && isOpen());
return this;
} finally {
@@ -518,8 +487,7 @@ public FileChannel truncate(long newSize) throws IOException {
}
}
- @Override
- public void force(boolean metaData) throws IOException {
+ private void implForce(boolean metaData) throws IOException {
ensureOpen();
int rv = -1;
int ti = -1;
@@ -529,11 +497,11 @@ public void force(boolean metaData) throws IOException {
if (!isOpen())
return;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
rv = nd.force(fd, metaData);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
} finally {
@@ -543,6 +511,17 @@ public void force(boolean metaData) throws IOException {
}
}
+ @Override
+ public void force(boolean metaData) throws IOException {
+ if (!FileForceEvent.enabled()) {
+ implForce(metaData);
+ return;
+ }
+ long start = FileForceEvent.timestamp();
+ implForce(metaData);
+ FileForceEvent.offer(start, path, metaData);
+ }
+
// Assume at first that the underlying kernel supports sendfile/equivalent;
// set this to true if we find out later that it doesn't
//
@@ -624,12 +603,7 @@ private long transferToFileDescriptor(long position, int count, FileDescriptor t
long n;
boolean append = fdAccess.getAppend(targetFD);
do {
- long comp = Blocker.begin();
- try {
- n = nd.transferTo(fd, position, count, targetFD, append);
- } finally {
- Blocker.end(comp);
- }
+ n = nd.transferTo(fd, position, count, targetFD, append);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return n;
}
@@ -895,12 +869,7 @@ private long transferFromFileDescriptor(FileDescriptor srcFD, long position, lon
long n;
boolean append = fdAccess.getAppend(fd);
do {
- long comp = Blocker.begin();
- try {
- n = nd.transferFrom(srcFD, fd, position, count, append);
- } finally {
- Blocker.end(comp);
- }
+ n = nd.transferFrom(srcFD, fd, position, count, append);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return n;
}
@@ -1088,11 +1057,11 @@ private int readInternal(ByteBuffer dst, long position) throws IOException {
if (!isOpen())
return -1;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(direct);
try {
n = IOUtil.read(fd, dst, position, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
@@ -1133,11 +1102,11 @@ private int writeInternal(ByteBuffer src, long position) throws IOException {
if (!isOpen())
return -1;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(sync || direct);
try {
n = IOUtil.write(fd, src, position, direct, alignment, nd);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
@@ -1362,12 +1331,7 @@ private Unmapper mapInternal(MapMode mode, long position, long size, int prot, b
synchronized (positionLock) {
long filesize;
do {
- long comp = Blocker.begin();
- try {
- filesize = nd.size(fd);
- } finally {
- Blocker.end(comp);
- }
+ filesize = nd.size(fd);
} while ((filesize == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -1379,12 +1343,7 @@ private Unmapper mapInternal(MapMode mode, long position, long size, int prot, b
}
int rv;
do {
- long comp = Blocker.begin();
- try {
- rv = nd.truncate(fd, position + size);
- } finally {
- Blocker.end(comp);
- }
+ rv = nd.truncate(fd, position + size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -1575,11 +1534,11 @@ public FileLock lock(long position, long size, boolean shared)
return null;
int n;
do {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
n = nd.lock(fd, true, position, size, shared);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} while ((n == FileDispatcher.INTERRUPTED) && isOpen());
if (isOpen()) {
diff --git a/src/java.base/share/classes/sun/nio/ch/Interruptible.java b/src/java.base/share/classes/sun/nio/ch/Interruptible.java
index 5785ba52e24..b5d9a7d2b3f 100644
--- a/src/java.base/share/classes/sun/nio/ch/Interruptible.java
+++ b/src/java.base/share/classes/sun/nio/ch/Interruptible.java
@@ -23,12 +23,12 @@
* questions.
*/
+package sun.nio.ch;
+
/**
* An object that interrupts a thread blocked in an I/O operation.
*/
-package sun.nio.ch;
-
public interface Interruptible {
/**
diff --git a/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java
index b41430c8d9d..5f3f91e7aff 100644
--- a/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java
+++ b/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package sun.nio.ch;
+import jdk.internal.event.FileForceEvent;
+
import java.nio.channels.*;
import java.util.concurrent.*;
import java.nio.ByteBuffer;
@@ -50,19 +52,25 @@ private static class DefaultExecutorHolder {
// Used to make native read and write calls
private static final FileDispatcher nd = new FileDispatcherImpl();
+ // file path
+ private final String path;
+
// Thread-safe set of IDs of native threads, for signalling
private final NativeThreadSet threads = new NativeThreadSet(2);
SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj,
+ String path,
boolean reading,
boolean writing,
ExecutorService executor)
{
super(fdObj, reading, writing, executor);
+ this.path = path;
}
public static AsynchronousFileChannel open(FileDescriptor fdo,
+ String path,
boolean reading,
boolean writing,
ThreadPool pool)
@@ -70,7 +78,7 @@ public static AsynchronousFileChannel open(FileDescriptor fdo,
// Executor is either default or based on pool parameters
ExecutorService executor = (pool == null) ?
DefaultExecutorHolder.defaultExecutor : pool.executor();
- return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor);
+ return new SimpleAsynchronousFileChannelImpl(fdo, path, reading, writing, executor);
}
@Override
@@ -151,8 +159,7 @@ public AsynchronousFileChannel truncate(long size) throws IOException {
}
}
- @Override
- public void force(boolean metaData) throws IOException {
+ private void implForce(boolean metaData) throws IOException {
int ti = threads.add();
try {
int n = 0;
@@ -169,6 +176,17 @@ public void force(boolean metaData) throws IOException {
}
}
+ @Override
+ public void force(boolean metaData) throws IOException {
+ if (!FileForceEvent.enabled()) {
+ implForce(metaData);
+ return;
+ }
+ long start = FileForceEvent.timestamp();
+ implForce(metaData);
+ FileForceEvent.offer(start, path, metaData);
+ }
+
@Override
Future implLock(final long position,
final long size,
diff --git a/src/java.base/share/classes/sun/security/ec/SunEC.java b/src/java.base/share/classes/sun/security/ec/SunEC.java
index 87385f1dea0..2e49b0af934 100644
--- a/src/java.base/share/classes/sun/security/ec/SunEC.java
+++ b/src/java.base/share/classes/sun/security/ec/SunEC.java
@@ -25,7 +25,7 @@
/*
* ===========================================================================
- * (c) Copyright IBM Corp. 2022, 2023 All Rights Reserved
+ * (c) Copyright IBM Corp. 2022, 2024 All Rights Reserved
* ===========================================================================
*/
@@ -75,6 +75,11 @@ public final class SunEC extends Provider {
*/
private static final boolean useNativeECKeyGen = NativeCrypto.isAlgorithmEnabled("jdk.nativeECKeyGen", "SunEC");
+ /* The property 'jdk.nativeECDSA' is used to control enablement of the native
+ * ECDSA signature implementation.
+ */
+ private static final boolean useNativeECDSA = NativeCrypto.isAlgorithmEnabled("jdk.nativeECDSA", "SunEC");
+
/* The property 'jdk.nativeXDHKeyAgreement' is used to control enablement of the native
* XDH key agreement. XDH key agreement is only supported in OpenSSL 1.1.1 and above.
*/
@@ -130,37 +135,96 @@ public Object newInstance(Object ctrParamObj)
if (inP1363) {
algo = algo.substring(0, algo.length() - 13);
}
- if (algo.equals("SHA1withECDSA")) {
- return (inP1363? new ECDSASignature.SHA1inP1363Format() :
- new ECDSASignature.SHA1());
- } else if (algo.equals("SHA224withECDSA")) {
- return (inP1363? new ECDSASignature.SHA224inP1363Format() :
- new ECDSASignature.SHA224());
- } else if (algo.equals("SHA256withECDSA")) {
- return (inP1363? new ECDSASignature.SHA256inP1363Format() :
- new ECDSASignature.SHA256());
- } else if (algo.equals("SHA384withECDSA")) {
- return (inP1363? new ECDSASignature.SHA384inP1363Format() :
- new ECDSASignature.SHA384());
- } else if (algo.equals("SHA512withECDSA")) {
- return (inP1363? new ECDSASignature.SHA512inP1363Format() :
- new ECDSASignature.SHA512());
- } else if (algo.equals("NONEwithECDSA")) {
- return (inP1363? new ECDSASignature.RawinP1363Format() :
- new ECDSASignature.Raw());
- } else if (algo.equals("SHA3-224withECDSA")) {
- return (inP1363? new ECDSASignature.SHA3_224inP1363Format() :
- new ECDSASignature.SHA3_224());
- } else if (algo.equals("SHA3-256withECDSA")) {
- return (inP1363? new ECDSASignature.SHA3_256inP1363Format() :
- new ECDSASignature.SHA3_256());
- } else if (algo.equals("SHA3-384withECDSA")) {
- return (inP1363? new ECDSASignature.SHA3_384inP1363Format() :
- new ECDSASignature.SHA3_384());
- } else if (algo.equals("SHA3-512withECDSA")) {
- return (inP1363? new ECDSASignature.SHA3_512inP1363Format() :
- new ECDSASignature.SHA3_512());
- }
+ if (useNativeECDSA
+ && (NativeCrypto.getVersionIfAvailable() >= NativeCrypto.OPENSSL_VERSION_1_1_1)
+ ) {
+ if (nativeCryptTrace) {
+ System.err.println("ECDSA Signature - Using OpenSSL integration.");
+ }
+ if (algo.equals("SHA1withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA1inP1363Format()
+ : new NativeECDSASignature.SHA1();
+ } else if (algo.equals("SHA224withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA224inP1363Format()
+ : new NativeECDSASignature.SHA224();
+ } else if (algo.equals("SHA256withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA256inP1363Format()
+ : new NativeECDSASignature.SHA256();
+ } else if (algo.equals("SHA384withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA384inP1363Format()
+ : new NativeECDSASignature.SHA384();
+ } else if (algo.equals("SHA512withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA512inP1363Format()
+ : new NativeECDSASignature.SHA512();
+ } else if (algo.equals("NONEwithECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.RawinP1363Format()
+ : new NativeECDSASignature.Raw();
+ } else if (algo.equals("SHA3-224withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA3_224inP1363Format()
+ : new NativeECDSASignature.SHA3_224();
+ } else if (algo.equals("SHA3-256withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA3_256inP1363Format()
+ : new NativeECDSASignature.SHA3_256();
+ } else if (algo.equals("SHA3-384withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA3_384inP1363Format()
+ : new NativeECDSASignature.SHA3_384();
+ } else if (algo.equals("SHA3-512withECDSA")) {
+ return inP1363
+ ? new NativeECDSASignature.SHA3_512inP1363Format()
+ : new NativeECDSASignature.SHA3_512();
+ }
+ } else {
+ if (algo.equals("SHA1withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA1inP1363Format()
+ : new ECDSASignature.SHA1();
+ } else if (algo.equals("SHA224withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA224inP1363Format()
+ : new ECDSASignature.SHA224();
+ } else if (algo.equals("SHA256withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA256inP1363Format()
+ : new ECDSASignature.SHA256();
+ } else if (algo.equals("SHA384withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA384inP1363Format()
+ : new ECDSASignature.SHA384();
+ } else if (algo.equals("SHA512withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA512inP1363Format()
+ : new ECDSASignature.SHA512();
+ } else if (algo.equals("NONEwithECDSA")) {
+ return inP1363
+ ? new ECDSASignature.RawinP1363Format()
+ : new ECDSASignature.Raw();
+ } else if (algo.equals("SHA3-224withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA3_224inP1363Format()
+ : new ECDSASignature.SHA3_224();
+ } else if (algo.equals("SHA3-256withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA3_256inP1363Format()
+ : new ECDSASignature.SHA3_256();
+ } else if (algo.equals("SHA3-384withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA3_384inP1363Format()
+ : new ECDSASignature.SHA3_384();
+ } else if (algo.equals("SHA3-512withECDSA")) {
+ return inP1363
+ ? new ECDSASignature.SHA3_512inP1363Format()
+ : new ECDSASignature.SHA3_512();
+ }
+ }
} else if (type.equals("KeyFactory")) {
if (algo.equals("EC")) {
return new ECKeyFactory();
@@ -403,68 +467,135 @@ void putEntries() {
/*
* Signature engines
*/
- putService(new ProviderService(this, "Signature",
- "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw",
- null, ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384",
- ATTRS));
- putService(new ProviderServiceA(this, "Signature",
- "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512",
- ATTRS));
+ if (useNativeECDSA
+ && (NativeCrypto.getVersionIfAvailable() >= NativeCrypto.OPENSSL_VERSION_1_1_1)
+ ) {
+ putService(new ProviderService(this, "Signature",
+ "NONEwithECDSA", "sun.security.ec.NativeECDSASignature$Raw",
+ null, ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA1withECDSA", "sun.security.ec.NativeECDSASignature$SHA1",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA224withECDSA", "sun.security.ec.NativeECDSASignature$SHA224",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA256withECDSA", "sun.security.ec.NativeECDSASignature$SHA256",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA384withECDSA", "sun.security.ec.NativeECDSASignature$SHA384",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA512withECDSA", "sun.security.ec.NativeECDSASignature$SHA512",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-224withECDSA", "sun.security.ec.NativeECDSASignature$SHA3_224",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-256withECDSA", "sun.security.ec.NativeECDSASignature$SHA3_256",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-384withECDSA", "sun.security.ec.NativeECDSASignature$SHA3_384",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-512withECDSA", "sun.security.ec.NativeECDSASignature$SHA3_512",
+ ATTRS));
- putService(new ProviderService(this, "Signature",
- "NONEwithECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$RawinP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA1withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA1inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA224withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA224inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA256withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA256inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA384withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA384inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA512withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA512inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "NONEwithECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$RawinP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA1withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA1inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA224withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA224inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA256withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA256inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA384withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA384inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA512withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA512inP1363Format"));
+
+ putService(new ProviderService(this, "Signature",
+ "SHA3-224withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA3_224inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-256withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA3_256inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-384withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA3_384inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-512withECDSAinP1363Format",
+ "sun.security.ec.NativeECDSASignature$SHA3_512inP1363Format"));
+ } else {
+ putService(new ProviderService(this, "Signature",
+ "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw",
+ null, ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384",
+ ATTRS));
+ putService(new ProviderServiceA(this, "Signature",
+ "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512",
+ ATTRS));
- putService(new ProviderService(this, "Signature",
- "SHA3-224withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA3_224inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA3-256withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA3_256inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA3-384withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA3_384inP1363Format"));
- putService(new ProviderService(this, "Signature",
- "SHA3-512withECDSAinP1363Format",
- "sun.security.ec.ECDSASignature$SHA3_512inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "NONEwithECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$RawinP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA1withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA1inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA224withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA224inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA256withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA256inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA384withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA384inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA512withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA512inP1363Format"));
+
+ putService(new ProviderService(this, "Signature",
+ "SHA3-224withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA3_224inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-256withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA3_256inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-384withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA3_384inP1363Format"));
+ putService(new ProviderService(this, "Signature",
+ "SHA3-512withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA3_512inP1363Format"));
+ }
/*
* Key Pair Generator engine
@@ -475,7 +606,7 @@ void putEntries() {
&& !isAIX
) {
putService(new ProviderServiceA(this, "KeyPairGenerator",
- "EC", "sun.security.ec.NaticeECKeyPairGenerator", ATTRS));
+ "EC", "sun.security.ec.NativeECKeyPairGenerator", ATTRS));
} else {
putService(new ProviderServiceA(this, "KeyPairGenerator",
"EC", "sun.security.ec.ECKeyPairGenerator", ATTRS));
diff --git a/src/java.base/share/classes/sun/security/jca/ProviderList.java b/src/java.base/share/classes/sun/security/jca/ProviderList.java
index 19cdb4f10a5..b1b230431ca 100644
--- a/src/java.base/share/classes/sun/security/jca/ProviderList.java
+++ b/src/java.base/share/classes/sun/security/jca/ProviderList.java
@@ -397,10 +397,13 @@ public Service getService(String type, String name) {
int i;
// Preferred provider list
- if (preferredPropList != null &&
- (pList = preferredPropList.getAll(type, name)) != null) {
+ if (preferredPropList != null) {
+ pList = preferredPropList.getAll(type, name);
for (i = 0; i < pList.size(); i++) {
Provider p = getProvider(pList.get(i).provider);
+ if (p == null) {
+ continue;
+ }
Service s = p.getService(type, name);
if ((s != null) && RestrictedSecurity.isServiceAllowed(s)) {
// We found a service that is allowed in restricted security mode.
@@ -408,7 +411,6 @@ public Service getService(String type, String name) {
}
}
}
-
for (i = 0; i < configs.length; i++) {
Provider p = getProvider(i);
Service s = p.getService(type, name);
diff --git a/src/java.base/share/classes/sun/security/pkcs/ParsingException.java b/src/java.base/share/classes/sun/security/pkcs/ParsingException.java
index d0f5999013d..ea7571491a0 100644
--- a/src/java.base/share/classes/sun/security/pkcs/ParsingException.java
+++ b/src/java.base/share/classes/sun/security/pkcs/ParsingException.java
@@ -23,16 +23,15 @@
* questions.
*/
+package sun.security.pkcs;
+
+import java.io.IOException;
+
/**
* Generic PKCS Parsing exception.
*
* @author Benjamin Renaud
*/
-
-package sun.security.pkcs;
-
-import java.io.IOException;
-
public class ParsingException extends IOException {
@java.io.Serial
diff --git a/src/java.base/share/classes/sun/security/provider/SeedGenerator.java b/src/java.base/share/classes/sun/security/provider/SeedGenerator.java
index 94ffc26ab3f..b4c9355bccf 100644
--- a/src/java.base/share/classes/sun/security/provider/SeedGenerator.java
+++ b/src/java.base/share/classes/sun/security/provider/SeedGenerator.java
@@ -25,6 +25,17 @@
package sun.security.provider;
+import java.security.*;
+import java.io.*;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.net.*;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Random;
+import sun.security.util.Debug;
+
/**
* This class generates seeds for the SHA1PRNG cryptographically strong
* random number generator.
@@ -66,17 +77,6 @@
* @author Gadi Guy
*/
-import java.security.*;
-import java.io.*;
-import java.util.Properties;
-import java.util.Enumeration;
-import java.net.*;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Random;
-import sun.security.util.Debug;
-
abstract class SeedGenerator {
// Static instance is created at link time
diff --git a/src/java.base/share/classes/sun/security/util/ByteArrayTagOrder.java b/src/java.base/share/classes/sun/security/util/ByteArrayTagOrder.java
index dd5fae526ac..65f20ac816c 100644
--- a/src/java.base/share/classes/sun/security/util/ByteArrayTagOrder.java
+++ b/src/java.base/share/classes/sun/security/util/ByteArrayTagOrder.java
@@ -23,6 +23,9 @@
* questions.
*/
+package sun.security.util;
+
+import java.util.Comparator;
/**
* ByteArrayTagOrder: a class for comparing two DER encodings by the
@@ -31,10 +34,6 @@
* @author D. N. Hoover
*/
-package sun.security.util;
-
-import java.util.Comparator;
-
public class ByteArrayTagOrder implements Comparator {
/**
diff --git a/src/java.base/share/classes/sun/security/util/IOUtils.java b/src/java.base/share/classes/sun/security/util/IOUtils.java
index 4837e2b70a0..a103f36eb2c 100644
--- a/src/java.base/share/classes/sun/security/util/IOUtils.java
+++ b/src/java.base/share/classes/sun/security/util/IOUtils.java
@@ -23,16 +23,15 @@
* questions.
*/
-/**
- * IOUtils: A collection of IO-related public static methods.
- */
-
package sun.security.util;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
+/**
+ * IOUtils: A collection of IO-related public static methods.
+ */
public class IOUtils {
/**
diff --git a/src/java.base/share/legal/cldr.md b/src/java.base/share/legal/cldr.md
index e0d8102fb7f..97331fcba9f 100644
--- a/src/java.base/share/legal/cldr.md
+++ b/src/java.base/share/legal/cldr.md
@@ -1,14 +1,15 @@
-## Unicode Common Local Data Repository (CLDR) v44
+## Unicode Common Local Data Repository (CLDR) v45
### CLDR License
```
+
UNICODE LICENSE V3
COPYRIGHT AND PERMISSION NOTICE
-Copyright © 2019-2023 Unicode, Inc.
+Copyright © 1991-2024 Unicode, Inc.
NOTICE TO USER: Carefully read the following legal agreement. BY
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
@@ -44,4 +45,56 @@ not be used in advertising or otherwise to promote the sale, use or other
dealings in these Data Files or Software without prior written
authorization of the copyright holder.
+SPDX-License-Identifier: Unicode-3.0
+
+————————————
+
+Unicode® Copyright and Terms of Use
+For the general privacy policy governing access to this site, see the Unicode Privacy Policy.
+
+Unicode Copyright
+Copyright © 1991-2024 Unicode, Inc. All rights reserved.
+Definitions
+Unicode Data Files ("DATA FILES") include all data files under the directories:
+https://www.unicode.org/Public/
+https://www.unicode.org/reports/
+https://www.unicode.org/ivd/data/
+
+Unicode Data Files do not include PDF online code charts under the directory:
+https://www.unicode.org/Public/
+
+Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard
+or any source code or compiled code under the directories:
+https://www.unicode.org/Public/PROGRAMS/
+https://www.unicode.org/Public/cldr/
+http://site.icu-project.org/download/
+Terms of Use
+Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein.
+Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein.
+Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License.
+Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page.
+The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart.
+All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use.
+No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site.
+Modification is not permitted with respect to this document. All copies of this document must be verbatim.
+Restricted Rights Legend
+Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement.
+Warranties and Disclaimers
+This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time.
+If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase.
+EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE.
+Waiver of Damages
+In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives.
+Trademarks & Logos
+The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names.
+The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc.
+All third party trademarks referenced herein are the property of their respective owners.
+Miscellaneous
+Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum.
+Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent.
+Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income.
+Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect.
+Entire Agreement. This Agreement constitutes the entire agreement between the parties.
+
+
```
diff --git a/src/java.base/share/native/libzip/zip_util.c b/src/java.base/share/native/libzip/zip_util.c
index a996b450ad4..8f2f19c66a2 100644
--- a/src/java.base/share/native/libzip/zip_util.c
+++ b/src/java.base/share/native/libzip/zip_util.c
@@ -437,7 +437,7 @@ hash(const char *s)
static unsigned int
hashN(const char *s, int length)
{
- int h = 0;
+ unsigned int h = 0;
while (length-- > 0)
h = 31*h + *s++;
return h;
diff --git a/src/java.base/unix/classes/java/io/UnixFileSystem.java b/src/java.base/unix/classes/java/io/UnixFileSystem.java
index 682e9a69b56..18afb729c01 100644
--- a/src/java.base/unix/classes/java/io/UnixFileSystem.java
+++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package java.io;
import java.util.Properties;
-import jdk.internal.misc.Blocker;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
@@ -161,12 +160,7 @@ public String resolve(File f) {
@Override
public String canonicalize(String path) throws IOException {
- long comp = Blocker.begin();
- try {
- return canonicalize0(path);
- } finally {
- Blocker.end(comp);
- }
+ return canonicalize0(path);
}
private native String canonicalize0(String path) throws IOException;
@@ -176,25 +170,13 @@ public String canonicalize(String path) throws IOException {
@Override
public int getBooleanAttributes(File f) {
- int rv;
- long comp = Blocker.begin();
- try {
- rv = getBooleanAttributes0(f);
- } finally {
- Blocker.end(comp);
- }
+ int rv = getBooleanAttributes0(f);
return rv | isHidden(f);
}
@Override
public boolean hasBooleanAttributes(File f, int attributes) {
- int rv;
- long comp = Blocker.begin();
- try {
- rv = getBooleanAttributes0(f);
- } finally {
- Blocker.end(comp);
- }
+ int rv = getBooleanAttributes0(f);
if ((attributes & BA_HIDDEN) != 0) {
rv |= isHidden(f);
}
@@ -207,45 +189,25 @@ private static int isHidden(File f) {
@Override
public boolean checkAccess(File f, int access) {
- long comp = Blocker.begin();
- try {
- return checkAccess0(f, access);
- } finally {
- Blocker.end(comp);
- }
+ return checkAccess0(f, access);
}
private native boolean checkAccess0(File f, int access);
@Override
public long getLastModifiedTime(File f) {
- long comp = Blocker.begin();
- try {
- return getLastModifiedTime0(f);
- } finally {
- Blocker.end(comp);
- }
+ return getLastModifiedTime0(f);
}
private native long getLastModifiedTime0(File f);
@Override
public long getLength(File f) {
- long comp = Blocker.begin();
- try {
- return getLength0(f);
- } finally {
- Blocker.end(comp);
- }
+ return getLength0(f);
}
private native long getLength0(File f);
@Override
public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
- long comp = Blocker.begin();
- try {
- return setPermission0(f, access, enable, owneronly);
- } finally {
- Blocker.end(comp);
- }
+ return setPermission0(f, access, enable, owneronly);
}
private native boolean setPermission0(File f, int access, boolean enable, boolean owneronly);
@@ -253,78 +215,43 @@ public boolean setPermission(File f, int access, boolean enable, boolean owneron
@Override
public boolean createFileExclusively(String path) throws IOException {
- long comp = Blocker.begin();
- try {
- return createFileExclusively0(path);
- } finally {
- Blocker.end(comp);
- }
+ return createFileExclusively0(path);
}
private native boolean createFileExclusively0(String path) throws IOException;
@Override
public boolean delete(File f) {
- long comp = Blocker.begin();
- try {
- return delete0(f);
- } finally {
- Blocker.end(comp);
- }
+ return delete0(f);
}
private native boolean delete0(File f);
@Override
public String[] list(File f) {
- long comp = Blocker.begin();
- try {
- return list0(f);
- } finally {
- Blocker.end(comp);
- }
+ return list0(f);
}
private native String[] list0(File f);
@Override
public boolean createDirectory(File f) {
- long comp = Blocker.begin();
- try {
- return createDirectory0(f);
- } finally {
- Blocker.end(comp);
- }
+ return createDirectory0(f);
}
private native boolean createDirectory0(File f);
@Override
public boolean rename(File f1, File f2) {
- long comp = Blocker.begin();
- try {
- return rename0(f1, f2);
- } finally {
- Blocker.end(comp);
- }
+ return rename0(f1, f2);
}
private native boolean rename0(File f1, File f2);
@Override
public boolean setLastModifiedTime(File f, long time) {
- long comp = Blocker.begin();
- try {
- return setLastModifiedTime0(f, time);
- } finally {
- Blocker.end(comp);
- }
+ return setLastModifiedTime0(f, time);
}
private native boolean setLastModifiedTime0(File f, long time);
@Override
public boolean setReadOnly(File f) {
- long comp = Blocker.begin();
- try {
- return setReadOnly0(f);
- } finally {
- Blocker.end(comp);
- }
+ return setReadOnly0(f);
}
private native boolean setReadOnly0(File f);
@@ -348,12 +275,7 @@ public File[] listRoots() {
@Override
public long getSpace(File f, int t) {
- long comp = Blocker.begin();
- try {
- return getSpace0(f, t);
- } finally {
- Blocker.end(comp);
- }
+ return getSpace0(f, t);
}
private native long getSpace0(File f, int t);
diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java
index 3b302b23cd3..da4874b0181 100644
--- a/src/java.base/unix/classes/java/lang/ProcessImpl.java
+++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -626,7 +626,7 @@ public void close() throws IOException {
*/
private static class ProcessPipeOutputStream extends BufferedOutputStream {
ProcessPipeOutputStream(int fd) {
- super(new FileOutputStream(newFileDescriptor(fd)));
+ super(new PipeOutputStream(newFileDescriptor(fd)));
}
/** Called by the process reaper thread when the process exits. */
diff --git a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java
index 513c871e0e4..a3bff8d1e65 100644
--- a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java
+++ b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -111,11 +111,11 @@ protected int doSelect(Consumer action, long timeout)
int numPolled;
do {
long startTime = timedPoll ? System.nanoTime() : 0;
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin(blocking);
try {
numPolled = poll(pollArray.address(), pollArraySize, to);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
if (numPolled == IOStatus.INTERRUPTED && timedPoll) {
// timed poll interrupted so need to adjust timeout
diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java b/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java
index eed7bc4c575..8e5bf38882c 100644
--- a/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -131,8 +131,8 @@ static FileChannel newFileChannel(int dfd,
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode);
- return FileChannelImpl.open(fdObj, path.toString(), flags.read,
- flags.write, flags.direct, null);
+ return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write,
+ (flags.sync || flags.dsync), flags.direct, null);
}
/**
@@ -168,7 +168,7 @@ static AsynchronousFileChannel newAsynchronousFileChannel(UnixPath path,
// for now use simple implementation
FileDescriptor fdObj = open(-1, path, null, flags, mode);
- return SimpleAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
+ return SimpleAsynchronousFileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, pool);
}
/**
diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java
index a9e10a94be3..2b9ab775ed8 100644
--- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java
@@ -52,7 +52,6 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
-import jdk.internal.misc.Blocker;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.IOStatus;
import sun.security.action.GetPropertyAction;
@@ -682,7 +681,6 @@ void copyFile(UnixPath source,
// Some forms of direct copy do not work on zero size files
if (!directCopyNotSupported && attrs.size() > 0) {
// copy bytes to target using platform function
- long comp = Blocker.begin();
try {
int res = directCopy(fo, fi, addressToPollForCancel);
if (res == 0) {
@@ -692,8 +690,6 @@ void copyFile(UnixPath source,
}
} catch (UnixException x) {
x.rethrowAsIOException(source, target);
- } finally {
- Blocker.end(comp);
}
}
@@ -703,14 +699,11 @@ void copyFile(UnixPath source,
ByteBuffer buf =
sun.nio.ch.Util.getTemporaryDirectBuffer(bufferSize);
try {
- long comp = Blocker.begin();
try {
bufferedCopy(fo, fi, ((DirectBuffer)buf).address(),
bufferSize, addressToPollForCancel);
} catch (UnixException x) {
x.rethrowAsIOException(source, target);
- } finally {
- Blocker.end(comp);
}
} finally {
sun.nio.ch.Util.releaseTemporaryDirectBuffer(buf);
diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java
index 2404f883c9c..a069a9a04ba 100644
--- a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.util.function.Function;
-import jdk.internal.misc.Blocker;
/**
* Unix system and library calls.
@@ -67,12 +66,7 @@ static NativeBuffer copyToNativeBuffer(UnixPath path) {
*/
static int open(UnixPath path, int flags, int mode) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return open0(buffer.address(), flags, mode);
- } finally {
- Blocker.end(comp);
- }
+ return open0(buffer.address(), flags, mode);
}
}
private static native int open0(long pathAddress, int flags, int mode)
@@ -83,12 +77,7 @@ private static native int open0(long pathAddress, int flags, int mode)
*/
static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return openat0(dfd, buffer.address(), flags, mode);
- } finally {
- Blocker.end(comp);
- }
+ return openat0(dfd, buffer.address(), flags, mode);
}
}
private static native int openat0(int dfd, long pathAddress, int flags, int mode)
@@ -138,12 +127,7 @@ void close(int fd, Function mapper) throws X {
static void link(UnixPath existing, UnixPath newfile) throws UnixException {
try (NativeBuffer existingBuffer = copyToNativeBuffer(existing);
NativeBuffer newBuffer = copyToNativeBuffer(newfile)) {
- long comp = Blocker.begin();
- try {
- link0(existingBuffer.address(), newBuffer.address());
- } finally {
- Blocker.end(comp);
- }
+ link0(existingBuffer.address(), newBuffer.address());
}
}
private static native void link0(long existingAddress, long newAddress)
@@ -154,12 +138,7 @@ private static native void link0(long existingAddress, long newAddress)
*/
static void unlink(UnixPath path) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- unlink0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ unlink0(buffer.address());
}
}
private static native void unlink0(long pathAddress) throws UnixException;
@@ -169,12 +148,7 @@ static void unlink(UnixPath path) throws UnixException {
*/
static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- unlinkat0(dfd, buffer.address(), flag);
- } finally {
- Blocker.end(comp);
- }
+ unlinkat0(dfd, buffer.address(), flag);
}
}
private static native void unlinkat0(int dfd, long pathAddress, int flag)
@@ -185,12 +159,7 @@ private static native void unlinkat0(int dfd, long pathAddress, int flag)
*/
static void mknod(UnixPath path, int mode, long dev) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- mknod0(buffer.address(), mode, dev);
- } finally {
- Blocker.end(comp);
- }
+ mknod0(buffer.address(), mode, dev);
}
}
private static native void mknod0(long pathAddress, int mode, long dev)
@@ -202,12 +171,7 @@ private static native void mknod0(long pathAddress, int mode, long dev)
static void rename(UnixPath from, UnixPath to) throws UnixException {
try (NativeBuffer fromBuffer = copyToNativeBuffer(from);
NativeBuffer toBuffer = copyToNativeBuffer(to)) {
- long comp = Blocker.begin();
- try {
- rename0(fromBuffer.address(), toBuffer.address());
- } finally {
- Blocker.end(comp);
- }
+ rename0(fromBuffer.address(), toBuffer.address());
}
}
private static native void rename0(long fromAddress, long toAddress)
@@ -219,12 +183,7 @@ private static native void rename0(long fromAddress, long toAddress)
static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
try (NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to)) {
- long comp = Blocker.begin();
- try {
- renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
- } finally {
- Blocker.end(comp);
- }
+ renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
}
}
private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
@@ -235,12 +194,7 @@ private static native void renameat0(int fromfd, long fromAddress, int tofd, lon
*/
static void mkdir(UnixPath path, int mode) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- mkdir0(buffer.address(), mode);
- } finally {
- Blocker.end(comp);
- }
+ mkdir0(buffer.address(), mode);
}
}
private static native void mkdir0(long pathAddress, int mode) throws UnixException;
@@ -250,12 +204,7 @@ static void mkdir(UnixPath path, int mode) throws UnixException {
*/
static void rmdir(UnixPath path) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- rmdir0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ rmdir0(buffer.address());
}
}
private static native void rmdir0(long pathAddress) throws UnixException;
@@ -267,12 +216,7 @@ static void rmdir(UnixPath path) throws UnixException {
*/
static byte[] readlink(UnixPath path) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return readlink0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return readlink0(buffer.address());
}
}
private static native byte[] readlink0(long pathAddress) throws UnixException;
@@ -284,12 +228,7 @@ static byte[] readlink(UnixPath path) throws UnixException {
*/
static byte[] realpath(UnixPath path) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return realpath0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return realpath0(buffer.address());
}
}
private static native byte[] realpath0(long pathAddress) throws UnixException;
@@ -300,12 +239,7 @@ static byte[] realpath(UnixPath path) throws UnixException {
static void symlink(byte[] name1, UnixPath name2) throws UnixException {
try (NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
NativeBuffer linkBuffer = copyToNativeBuffer(name2)) {
- long comp = Blocker.begin();
- try {
- symlink0(targetBuffer.address(), linkBuffer.address());
- } finally {
- Blocker.end(comp);
- }
+ symlink0(targetBuffer.address(), linkBuffer.address());
}
}
private static native void symlink0(long name1, long name2)
@@ -316,26 +250,16 @@ private static native void symlink0(long name1, long name2)
*/
static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- int errno = stat0(buffer.address(), attrs);
- if (errno != 0) {
- throw new UnixException(errno);
- }
- } finally {
- Blocker.end(comp);
+ int errno = stat0(buffer.address(), attrs);
+ if (errno != 0) {
+ throw new UnixException(errno);
}
}
}
static int stat2(UnixPath path, UnixFileAttributes attrs) {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return stat0(buffer.address(), attrs);
- } finally {
- Blocker.end(comp);
- }
+ return stat0(buffer.address(), attrs);
}
}
@@ -346,12 +270,7 @@ static int stat2(UnixPath path, UnixFileAttributes attrs) {
*/
static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- lstat0(buffer.address(), attrs);
- } finally {
- Blocker.end(comp);
- }
+ lstat0(buffer.address(), attrs);
}
}
private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
@@ -361,12 +280,7 @@ private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
* fstat(int filedes, struct stat* buf)
*/
static void fstat(int fd, UnixFileAttributes attrs) throws UnixException {
- long comp = Blocker.begin();
- try {
- fstat0(fd, attrs);
- } finally {
- Blocker.end(comp);
- }
+ fstat0(fd, attrs);
}
private static native void fstat0(int fd, UnixFileAttributes attrs)
throws UnixException;
@@ -378,12 +292,7 @@ static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
throws UnixException
{
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- fstatat0(dfd, buffer.address(), flag, attrs);
- } finally {
- Blocker.end(comp);
- }
+ fstatat0(dfd, buffer.address(), flag, attrs);
}
}
private static native void fstatat0(int dfd, long pathAddress, int flag,
@@ -394,12 +303,7 @@ private static native void fstatat0(int dfd, long pathAddress, int flag,
*/
static void chown(UnixPath path, int uid, int gid) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- chown0(buffer.address(), uid, gid);
- } finally {
- Blocker.end(comp);
- }
+ chown0(buffer.address(), uid, gid);
}
}
private static native void chown0(long pathAddress, int uid, int gid)
@@ -410,12 +314,7 @@ private static native void chown0(long pathAddress, int uid, int gid)
*/
static void lchown(UnixPath path, int uid, int gid) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- lchown0(buffer.address(), uid, gid);
- } finally {
- Blocker.end(comp);
- }
+ lchown0(buffer.address(), uid, gid);
}
}
private static native void lchown0(long pathAddress, int uid, int gid)
@@ -425,12 +324,7 @@ private static native void lchown0(long pathAddress, int uid, int gid)
* fchown(int filedes, uid_t owner, gid_t group)
*/
static void fchown(int fd, int uid, int gid) throws UnixException {
- long comp = Blocker.begin();
- try {
- fchown0(fd, uid, gid);
- } finally {
- Blocker.end(comp);
- }
+ fchown0(fd, uid, gid);
}
static native void fchown0(int fd, int uid, int gid) throws UnixException;
@@ -439,12 +333,7 @@ static void fchown(int fd, int uid, int gid) throws UnixException {
*/
static void chmod(UnixPath path, int mode) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- chmod0(buffer.address(), mode);
- } finally {
- Blocker.end(comp);
- }
+ chmod0(buffer.address(), mode);
}
}
private static native void chmod0(long pathAddress, int mode)
@@ -454,12 +343,7 @@ private static native void chmod0(long pathAddress, int mode)
* fchmod(int fildes, mode_t mode)
*/
static void fchmod(int fd, int mode) throws UnixException {
- long comp = Blocker.begin();
- try {
- fchmod0(fd, mode);
- } finally {
- Blocker.end(comp);
- }
+ fchmod0(fd, mode);
}
private static native void fchmod0(int fd, int mode) throws UnixException;
@@ -470,12 +354,7 @@ static void utimes(UnixPath path, long times0, long times1)
throws UnixException
{
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- utimes0(buffer.address(), times0, times1);
- } finally {
- Blocker.end(comp);
- }
+ utimes0(buffer.address(), times0, times1);
}
}
private static native void utimes0(long pathAddress, long times0, long times1)
@@ -485,12 +364,7 @@ private static native void utimes0(long pathAddress, long times0, long times1)
* futimes(int fildes, const struct timeval times[2])
*/
static void futimes(int fd, long times0, long times1) throws UnixException {
- long comp = Blocker.begin();
- try {
- futimes0(fd, times0, times1);
- } finally {
- Blocker.end(comp);
- }
+ futimes0(fd, times0, times1);
}
private static native void futimes0(int fd, long times0, long times1)
throws UnixException;
@@ -499,12 +373,7 @@ private static native void futimes0(int fd, long times0, long times1)
* futimens(int fildes, const struct timespec times[2])
*/
static void futimens(int fd, long times0, long times1) throws UnixException {
- long comp = Blocker.begin();
- try {
- futimens0(fd, times0, times1);
- } finally {
- Blocker.end(comp);
- }
+ futimens0(fd, times0, times1);
}
private static native void futimens0(int fd, long times0, long times1)
throws UnixException;
@@ -516,12 +385,7 @@ static void lutimes(UnixPath path, long times0, long times1)
throws UnixException
{
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- lutimes0(buffer.address(), times0, times1);
- } finally {
- Blocker.end(comp);
- }
+ lutimes0(buffer.address(), times0, times1);
}
}
private static native void lutimes0(long pathAddress, long times0, long times1)
@@ -532,12 +396,7 @@ private static native void lutimes0(long pathAddress, long times0, long times1)
*/
static long opendir(UnixPath path) throws UnixException {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return opendir0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return opendir0(buffer.address());
}
}
private static native long opendir0(long pathAddress) throws UnixException;
@@ -559,12 +418,7 @@ static long opendir(UnixPath path) throws UnixException {
* @return dirent->d_name
*/
static byte[] readdir(long dir) throws UnixException {
- long comp = Blocker.begin();
- try {
- return readdir0(dir);
- } finally {
- Blocker.end(comp);
- }
+ return readdir0(dir);
}
static native byte[] readdir0(long dir) throws UnixException;
@@ -572,12 +426,7 @@ static byte[] readdir(long dir) throws UnixException {
* size_t read(int fildes, void* buf, size_t nbyte)
*/
static int read(int fildes, long buf, int nbyte) throws UnixException {
- long comp = Blocker.begin();
- try {
- return read0(fildes, buf, nbyte);
- } finally {
- Blocker.end(comp);
- }
+ return read0(fildes, buf, nbyte);
}
private static native int read0(int fildes, long buf, int nbyte) throws UnixException;
@@ -585,12 +434,7 @@ static int read(int fildes, long buf, int nbyte) throws UnixException {
* size_t writeint fildes, void* buf, size_t nbyte)
*/
static int write(int fildes, long buf, int nbyte) throws UnixException {
- long comp = Blocker.begin();
- try {
- return write0(fildes, buf, nbyte);
- } finally {
- Blocker.end(comp);
- }
+ return write0(fildes, buf, nbyte);
}
private static native int write0(int fildes, long buf, int nbyte) throws UnixException;
@@ -599,12 +443,7 @@ static int write(int fildes, long buf, int nbyte) throws UnixException {
*/
static int access(UnixPath path, int amode) {
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return access0(buffer.address(), amode);
- } finally {
- Blocker.end(comp);
- }
+ return access0(buffer.address(), amode);
}
}
private static native int access0(long pathAddress, int amode);
@@ -630,12 +469,7 @@ static int access(UnixPath path, int amode) {
*/
static int getpwnam(String name) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name))) {
- long comp = Blocker.begin();
- try {
- return getpwnam0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return getpwnam0(buffer.address());
}
}
private static native int getpwnam0(long nameAddress) throws UnixException;
@@ -647,12 +481,7 @@ static int getpwnam(String name) throws UnixException {
*/
static int getgrnam(String name) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name))) {
- long comp = Blocker.begin();
- try {
- return getgrnam0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return getgrnam0(buffer.address());
}
}
private static native int getgrnam0(long nameAddress) throws UnixException;
@@ -664,12 +493,7 @@ static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
throws UnixException
{
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- statvfs0(buffer.address(), attrs);
- } finally {
- Blocker.end(comp);
- }
+ statvfs0(buffer.address(), attrs);
}
}
private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
@@ -687,12 +511,7 @@ static int fgetxattr(int filedes, byte[] name, long valueAddress, int valueLen)
throws UnixException
{
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
- long comp = Blocker.begin();
- try {
- return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
- } finally {
- Blocker.end(comp);
- }
+ return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
}
}
@@ -706,12 +525,7 @@ static void fsetxattr(int filedes, byte[] name, long valueAddress, int valueLen)
throws UnixException
{
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
- long comp = Blocker.begin();
- try {
- fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
- } finally {
- Blocker.end(comp);
- }
+ fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
}
}
@@ -723,12 +537,7 @@ private static native void fsetxattr0(int filedes, long nameAddress,
*/
static void fremovexattr(int filedes, byte[] name) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
- long comp = Blocker.begin();
- try {
- fremovexattr0(filedes, buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ fremovexattr0(filedes, buffer.address());
}
}
diff --git a/src/java.base/unix/native/libjli/java_md.c b/src/java.base/unix/native/libjli/java_md.c
index a71206c77cb..7cde49ddaf6 100644
--- a/src/java.base/unix/native/libjli/java_md.c
+++ b/src/java.base/unix/native/libjli/java_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -544,6 +544,8 @@ GetJREPath(char *path, jint pathsize, jboolean speculative)
char libjava[MAXPATHLEN];
struct stat s;
+ JLI_TraceLauncher("Attempt to get JRE path from launcher executable path\n");
+
if (GetApplicationHome(path, pathsize)) {
/* Is JRE co-located with the application? */
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
@@ -551,20 +553,10 @@ GetJREPath(char *path, jint pathsize, jboolean speculative)
JLI_TraceLauncher("JRE path is %s\n", path);
return JNI_TRUE;
}
- /* ensure storage for path + /jre + NULL */
- if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
- JLI_TraceLauncher("Insufficient space to store JRE path\n");
- return JNI_FALSE;
- }
- /* Does the app ship a private JRE in /jre directory? */
- JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/" JAVA_DLL, path);
- if (access(libjava, F_OK) == 0) {
- JLI_StrCat(path, "/jre");
- JLI_TraceLauncher("JRE path is %s\n", path);
- return JNI_TRUE;
- }
}
+ JLI_TraceLauncher("Attempt to get JRE path from shared lib of the image\n");
+
if (GetApplicationHomeFromDll(path, pathsize)) {
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
if (stat(libjava, &s) == 0) {
diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
index e700d44cfae..cf58d980bbe 100644
--- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java
+++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
import java.util.BitSet;
import java.util.Locale;
import java.util.Properties;
-import jdk.internal.misc.Blocker;
import sun.security.action.GetPropertyAction;
/**
@@ -491,12 +490,7 @@ public String canonicalize(String path) throws IOException {
return path;
return "" + ((char) (c-32)) + ':' + '\\';
}
- long comp = Blocker.begin();
- try {
- return canonicalize0(path);
- } finally {
- Blocker.end(comp);
- }
+ return canonicalize0(path);
}
private native String canonicalize0(String path)
@@ -507,56 +501,31 @@ private native String canonicalize0(String path)
@Override
public int getBooleanAttributes(File f) {
- long comp = Blocker.begin();
- try {
- return getBooleanAttributes0(f);
- } finally {
- Blocker.end(comp);
- }
+ return getBooleanAttributes0(f);
}
private native int getBooleanAttributes0(File f);
@Override
public boolean checkAccess(File f, int access) {
- long comp = Blocker.begin();
- try {
- return checkAccess0(f, access);
- } finally {
- Blocker.end(comp);
- }
+ return checkAccess0(f, access);
}
private native boolean checkAccess0(File f, int access);
@Override
public long getLastModifiedTime(File f) {
- long comp = Blocker.begin();
- try {
- return getLastModifiedTime0(f);
- } finally {
- Blocker.end(comp);
- }
+ return getLastModifiedTime0(f);
}
private native long getLastModifiedTime0(File f);
@Override
public long getLength(File f) {
- long comp = Blocker.begin();
- try {
- return getLength0(f);
- } finally {
- Blocker.end(comp);
- }
+ return getLength0(f);
}
private native long getLength0(File f);
@Override
public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
- long comp = Blocker.begin();
- try {
- return setPermission0(f, access, enable, owneronly);
- } finally {
- Blocker.end(comp);
- }
+ return setPermission0(f, access, enable, owneronly);
}
private native boolean setPermission0(File f, int access, boolean enable, boolean owneronly);
@@ -564,78 +533,43 @@ public boolean setPermission(File f, int access, boolean enable, boolean owneron
@Override
public boolean createFileExclusively(String path) throws IOException {
- long comp = Blocker.begin();
- try {
- return createFileExclusively0(path);
- } finally {
- Blocker.end(comp);
- }
+ return createFileExclusively0(path);
}
private native boolean createFileExclusively0(String path) throws IOException;
@Override
public String[] list(File f) {
- long comp = Blocker.begin();
- try {
- return list0(f);
- } finally {
- Blocker.end(comp);
- }
+ return list0(f);
}
private native String[] list0(File f);
@Override
public boolean createDirectory(File f) {
- long comp = Blocker.begin();
- try {
- return createDirectory0(f);
- } finally {
- Blocker.end(comp);
- }
+ return createDirectory0(f);
}
private native boolean createDirectory0(File f);
@Override
public boolean setLastModifiedTime(File f, long time) {
- long comp = Blocker.begin();
- try {
- return setLastModifiedTime0(f, time);
- } finally {
- Blocker.end(comp);
- }
+ return setLastModifiedTime0(f, time);
}
private native boolean setLastModifiedTime0(File f, long time);
@Override
public boolean setReadOnly(File f) {
- long comp = Blocker.begin();
- try {
- return setReadOnly0(f);
- } finally {
- Blocker.end(comp);
- }
+ return setReadOnly0(f);
}
private native boolean setReadOnly0(File f);
@Override
public boolean delete(File f) {
- long comp = Blocker.begin();
- try {
- return delete0(f);
- } finally {
- Blocker.end(comp);
- }
+ return delete0(f);
}
private native boolean delete0(File f);
@Override
public boolean rename(File f1, File f2) {
- long comp = Blocker.begin();
- try {
- return rename0(f1, f2);
- } finally {
- Blocker.end(comp);
- }
+ return rename0(f1, f2);
}
private native boolean rename0(File f1, File f2);
diff --git a/src/java.base/windows/classes/java/lang/ProcessImpl.java b/src/java.base/windows/classes/java/lang/ProcessImpl.java
index a01d1db6ddc..d6fb51c4494 100644
--- a/src/java.base/windows/classes/java/lang/ProcessImpl.java
+++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -515,7 +515,7 @@ public Void run() {
fdAccess.setHandle(stdin_fd, stdHandles[0]);
fdAccess.registerCleanup(stdin_fd);
stdin_stream = new BufferedOutputStream(
- new FileOutputStream(stdin_fd));
+ new PipeOutputStream(stdin_fd));
}
if (stdHandles[1] == -1L || forceNullOutputStream)
@@ -564,11 +564,11 @@ public int exitValue() {
private static native int getExitCodeProcess(long handle);
public int waitFor() throws InterruptedException {
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
waitForInterruptibly(handle);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
if (Thread.interrupted())
throw new InterruptedException();
@@ -593,11 +593,11 @@ public boolean waitFor(long timeout, TimeUnit unit)
// if wraps around then wait a long while
msTimeout = Integer.MAX_VALUE;
}
- long comp = Blocker.begin();
+ boolean attempted = Blocker.begin();
try {
waitForTimeoutInterruptibly(handle, msTimeout);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
if (Thread.interrupted())
throw new InterruptedException();
diff --git a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java
index 2b39a7ed4a9..bbcfab9bbf1 100644
--- a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java
+++ b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -109,11 +109,11 @@ protected int doSelect(Consumer action, long timeout)
processDeregisterQueue();
try {
begin(blocking);
- long comp = Blocker.begin(blocking);
+ boolean attempted = Blocker.begin(blocking);
try {
numEntries = WEPoll.wait(eph, pollArrayAddress, NUM_EPOLLEVENTS, to);
} finally {
- Blocker.end(comp);
+ Blocker.end(attempted);
}
} finally {
end(blocking);
diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
index a1bacc1fae1..15ae425850e 100644
--- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
+++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
import java.io.FileDescriptor;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
+import jdk.internal.event.FileForceEvent;
/**
* Windows implementation of AsynchronousFileChannel using overlapped I/O.
@@ -63,6 +64,9 @@ private static Iocp defaultIocp() {
// Used for force/truncate/size methods
private static final FileDispatcher nd = new FileDispatcherImpl();
+ // file path
+ private final String path;
+
// The handle is extracted for use in native methods invoked from this class.
private final long handle;
@@ -79,6 +83,7 @@ private static Iocp defaultIocp() {
private WindowsAsynchronousFileChannelImpl(FileDescriptor fdObj,
+ String path,
boolean reading,
boolean writing,
Iocp iocp,
@@ -86,6 +91,7 @@ private WindowsAsynchronousFileChannelImpl(FileDescriptor fdObj,
throws IOException
{
super(fdObj, reading, writing, iocp.executor());
+ this.path = path;
this.handle = fdAccess.getHandle(fdObj);
this.iocp = iocp;
this.isDefaultIocp = isDefaultIocp;
@@ -94,6 +100,7 @@ private WindowsAsynchronousFileChannelImpl(FileDescriptor fdObj,
}
public static AsynchronousFileChannel open(FileDescriptor fdo,
+ String path,
boolean reading,
boolean writing,
ThreadPool pool)
@@ -109,8 +116,7 @@ public static AsynchronousFileChannel open(FileDescriptor fdo,
isDefaultIocp = false;
}
try {
- return new
- WindowsAsynchronousFileChannelImpl(fdo, reading, writing, iocp, isDefaultIocp);
+ return new WindowsAsynchronousFileChannelImpl(fdo, path, reading, writing, iocp, isDefaultIocp);
} catch (IOException x) {
// error binding to port so need to close it (if created for this channel)
if (!isDefaultIocp)
@@ -196,8 +202,7 @@ public AsynchronousFileChannel truncate(long size) throws IOException {
return this;
}
- @Override
- public void force(boolean metaData) throws IOException {
+ private void implForce(boolean metaData) throws IOException {
try {
begin();
nd.force(fdObj, metaData);
@@ -206,6 +211,17 @@ public void force(boolean metaData) throws IOException {
}
}
+ @Override
+ public void force(boolean metaData) throws IOException {
+ if (!FileForceEvent.enabled()) {
+ implForce(metaData);
+ return;
+ }
+ long start = FileForceEvent.timestamp();
+ implForce(metaData);
+ FileForceEvent.offer(start, path, metaData);
+ }
+
// -- file locking --
/**
diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java b/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java
index 56f09d34ab8..59db82d3fab 100644
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -166,8 +166,8 @@ static FileChannel newFileChannel(String pathForWindows,
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
- return FileChannelImpl.open(fdObj, pathForWindows, flags.read,
- flags.write, flags.direct, null);
+ return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write,
+ (flags.sync || flags.dsync), flags.direct, null);
}
/**
@@ -212,7 +212,7 @@ static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows,
// create the AsynchronousFileChannel
try {
- return WindowsAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
+ return WindowsAsynchronousFileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, pool);
} catch (IOException x) {
// IOException is thrown if the file handle cannot be associated
// with the completion port. All we can do is close the file.
diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java b/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
index 34d748f4150..8e351b7e0ef 100644
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package sun.nio.fs;
-import jdk.internal.misc.Blocker;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsConstants.*;
@@ -68,17 +67,12 @@ static long CreateFile(String path,
throws WindowsException
{
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return CreateFile0(buffer.address(),
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes);
- } finally {
- Blocker.end(comp);
- }
+ return CreateFile0(buffer.address(),
+ dwDesiredAccess,
+ dwShareMode,
+ lpSecurityAttributes,
+ dwCreationDisposition,
+ dwFlagsAndAttributes);
}
}
static long CreateFile(String path,
@@ -113,12 +107,7 @@ private static native long CreateFile0(long lpFileName,
*/
static void DeleteFile(String path) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- DeleteFile0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ DeleteFile0(buffer.address());
}
}
private static native void DeleteFile0(long lpFileName)
@@ -132,12 +121,7 @@ private static native void DeleteFile0(long lpFileName)
*/
static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- CreateDirectory0(buffer.address(), lpSecurityAttributes);
- } finally {
- Blocker.end(comp);
- }
+ CreateDirectory0(buffer.address(), lpSecurityAttributes);
}
}
private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
@@ -150,12 +134,7 @@ private static native void CreateDirectory0(long lpFileName, long lpSecurityAttr
*/
static void RemoveDirectory(String path) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- RemoveDirectory0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ RemoveDirectory0(buffer.address());
}
}
private static native void RemoveDirectory0(long lpFileName)
@@ -200,12 +179,7 @@ static native void DeviceIoControlGetReparsePoint(long handle,
static FirstFile FindFirstFile(String path) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
FirstFile data = new FirstFile();
- long comp = Blocker.begin();
- try {
- FindFirstFile0(buffer.address(), data);
- } finally {
- Blocker.end(comp);
- }
+ FindFirstFile0(buffer.address(), data);
return data;
}
}
@@ -230,12 +204,7 @@ private static native void FindFirstFile0(long lpFileName, FirstFile obj)
*/
static long FindFirstFile(String path, long address) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return FindFirstFile1(buffer.address(), address);
- } finally {
- Blocker.end(comp);
- }
+ return FindFirstFile1(buffer.address(), address);
}
}
private static native long FindFirstFile1(long lpFileName, long address)
@@ -250,12 +219,7 @@ private static native long FindFirstFile1(long lpFileName, long address)
* @return lpFindFileData->cFileName or null
*/
static String FindNextFile(long handle, long address) throws WindowsException {
- long comp = Blocker.begin();
- try {
- return FindNextFile0(handle, address);
- } finally {
- Blocker.end(comp);
- }
+ return FindNextFile0(handle, address);
}
private static native String FindNextFile0(long handle, long address)
throws WindowsException;
@@ -271,12 +235,7 @@ private static native String FindNextFile0(long handle, long address)
static FirstStream FindFirstStream(String path) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
FirstStream data = new FirstStream();
- long comp = Blocker.begin();
- try {
- FindFirstStream0(buffer.address(), data);
- } finally {
- Blocker.end(comp);
- }
+ FindFirstStream0(buffer.address(), data);
if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)
return null;
return data;
@@ -300,12 +259,7 @@ private static native void FindFirstStream0(long lpFileName, FirstStream obj)
* )
*/
static String FindNextStream(long handle) throws WindowsException {
- long comp = Blocker.begin();
- try {
- return FindNextStream0(handle);
- } finally {
- Blocker.end(comp);
- }
+ return FindNextStream0(handle);
}
private static native String FindNextStream0(long handle) throws WindowsException;
@@ -325,12 +279,7 @@ static String FindNextStream(long handle) throws WindowsException {
static void GetFileInformationByHandle(long handle, long address)
throws WindowsException
{
- long comp = Blocker.begin();
- try {
- GetFileInformationByHandle0(handle, address);
- } finally {
- Blocker.end(comp);
- }
+ GetFileInformationByHandle0(handle, address);
}
private static native void GetFileInformationByHandle0(long handle, long address)
throws WindowsException;
@@ -351,13 +300,7 @@ static void CopyFileEx(String source, String target, int flags,
{
try (NativeBuffer sourceBuffer = asNativeBuffer(source);
NativeBuffer targetBuffer = asNativeBuffer(target)) {
- long comp = Blocker.begin();
- try {
- CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,
- addressToPollForCancel);
- } finally {
- Blocker.end(comp);
- }
+ CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags, addressToPollForCancel);
}
}
private static native void CopyFileEx0(long existingAddress, long newAddress,
@@ -375,12 +318,7 @@ static void MoveFileEx(String source, String target, int flags)
{
try (NativeBuffer sourceBuffer = asNativeBuffer(source);
NativeBuffer targetBuffer = asNativeBuffer(target)) {
- long comp = Blocker.begin();
- try {
- MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
- } finally {
- Blocker.end(comp);
- }
+ MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
}
}
private static native void MoveFileEx0(long existingAddress, long newAddress,
@@ -393,12 +331,7 @@ private static native void MoveFileEx0(long existingAddress, long newAddress,
*/
static int GetFileAttributes(String path) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- return GetFileAttributes0(buffer.address());
- } finally {
- Blocker.end(comp);
- }
+ return GetFileAttributes0(buffer.address());
}
}
private static native int GetFileAttributes0(long lpFileName)
@@ -413,12 +346,7 @@ static void SetFileAttributes(String path, int dwFileAttributes)
throws WindowsException
{
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- SetFileAttributes0(buffer.address(), dwFileAttributes);
- } finally {
- Blocker.end(comp);
- }
+ SetFileAttributes0(buffer.address(), dwFileAttributes);
}
}
private static native void SetFileAttributes0(long lpFileName,
@@ -433,12 +361,7 @@ private static native void SetFileAttributes0(long lpFileName,
*/
static void GetFileAttributesEx(String path, long address) throws WindowsException {
try (NativeBuffer buffer = asNativeBuffer(path)) {
- long comp = Blocker.begin();
- try {
- GetFileAttributesEx0(buffer.address(), address);
- } finally {
- Blocker.end(comp);
- }
+ GetFileAttributesEx0(buffer.address(), address);
}
}
private static native void GetFileAttributesEx0(long lpFileName, long address)
@@ -455,12 +378,7 @@ private static native void GetFileAttributesEx0(long lpFileName, long address)
static void SetFileTime(long handle, long createTime, long lastAccessTime, long lastWriteTime)
throws WindowsException
{
- long comp = Blocker.begin();
- try {
- SetFileTime0(handle, createTime, lastAccessTime, lastWriteTime);
- } finally {
- Blocker.end(comp);
- }
+ SetFileTime0(handle, createTime, lastAccessTime, lastWriteTime);
}
private static native void SetFileTime0(long handle,
long createTime,
diff --git a/src/java.base/windows/native/libjli/java_md.c b/src/java.base/windows/native/libjli/java_md.c
index 39930a38535..6ff155bcb9b 100644
--- a/src/java.base/windows/native/libjli/java_md.c
+++ b/src/java.base/windows/native/libjli/java_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,10 +49,6 @@ static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
-#ifdef USE_REGISTRY_LOOKUP
-jboolean GetPublicJREHome(char *buf, jint bufsize);
-#endif
-
/* We supports warmup for UI stack that is performed in parallel
* to VM initialization.
* This helps to improve startup of UI application as warmup phase
@@ -300,6 +296,8 @@ GetJREPath(char *path, jint pathsize)
char javadll[MAXPATHLEN];
struct stat s;
+ JLI_TraceLauncher("Attempt to get JRE path from launcher executable path\n");
+
if (GetApplicationHome(path, pathsize)) {
/* Is JRE co-located with the application? */
JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path);
@@ -307,20 +305,10 @@ GetJREPath(char *path, jint pathsize)
JLI_TraceLauncher("JRE path is %s\n", path);
return JNI_TRUE;
}
- /* ensure storage for path + \jre + NULL */
- if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
- JLI_TraceLauncher("Insufficient space to store JRE path\n");
- return JNI_FALSE;
- }
- /* Does this app ship a private JRE in \jre directory? */
- JLI_Snprintf(javadll, sizeof (javadll), "%s\\jre\\bin\\" JAVA_DLL, path);
- if (stat(javadll, &s) == 0) {
- JLI_StrCat(path, "\\jre");
- JLI_TraceLauncher("JRE path is %s\n", path);
- return JNI_TRUE;
- }
}
+ JLI_TraceLauncher("Attempt to get JRE path from shared lib of the image\n");
+
/* Try getting path to JRE from path to JLI.DLL */
if (GetApplicationHomeFromDll(path, pathsize)) {
JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path);
@@ -330,14 +318,6 @@ GetJREPath(char *path, jint pathsize)
}
}
-#ifdef USE_REGISTRY_LOOKUP
- /* Lookup public JRE using Windows registry. */
- if (GetPublicJREHome(path, pathsize)) {
- JLI_TraceLauncher("JRE path is %s\n", path);
- return JNI_TRUE;
- }
-#endif
-
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
diff --git a/src/java.desktop/macosx/classes/sun/font/CStrike.java b/src/java.desktop/macosx/classes/sun/font/CStrike.java
index eb049c3d449..b0131711ca5 100644
--- a/src/java.desktop/macosx/classes/sun/font/CStrike.java
+++ b/src/java.desktop/macosx/classes/sun/font/CStrike.java
@@ -199,7 +199,7 @@ void getGlyphImageBounds(int glyphCode, Point2D.Float pt, Rectangle result) {
getGlyphImageBounds(glyphCode, pt.x, pt.y, floatRect);
if (floatRect.width == 0 && floatRect.height == 0) {
- result.setRect(0, 0, -1, -1);
+ result.setRect(0, 0, 0, 0);
return;
}
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
index f6e8fe6af55..ecdd6e4cdf8 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
@@ -1020,4 +1020,20 @@ @implementation CGGI_GlyphCanvas
CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, glyphs, advances, count);
}
}
-}
\ No newline at end of file
+ int MAX_SIZE = 1 << 30;
+ if (bboxes) {
+ for (int i = 0; i < count; i++) {
+ if (bboxes[i].origin.x > (double)MAX_SIZE) bboxes[i].origin.x = 0;
+ if (bboxes[i].origin.y > (double)MAX_SIZE) bboxes[i].origin.y = 0;
+ if (bboxes[i].size.width > (double)MAX_SIZE) bboxes[i].size.width = 0;
+ if (bboxes[i].size.height > (double)MAX_SIZE) bboxes[i].size.height = 0;
+ }
+ }
+ if (advances) {
+ for (int i = 0; i < count; i++) {
+ if (advances[i].width > (double)MAX_SIZE) advances[i].width = 0;
+ if (advances[i].height > (double)MAX_SIZE) advances[i].height = 0;
+ }
+ }
+}
+
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java
index fb24eca6611..de2a8b6306b 100644
--- a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java
+++ b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java
@@ -313,10 +313,10 @@ void readTrack(Track track) throws IOException, InvalidMidiDataException {
// reset current tick to 0
long tick = 0;
- // reset current status byte to 0 (invalid value).
+ // reset current running status byte to 0 (invalid value).
// this should cause us to throw an InvalidMidiDataException if we don't
// get a valid status byte from the beginning of the track.
- int status = 0;
+ int runningStatus = 0;
boolean endOfTrackFound = false;
while (!trackFinished() && !endOfTrackFound) {
@@ -333,10 +333,17 @@ void readTrack(Track track) throws IOException, InvalidMidiDataException {
// check for new status
int byteValue = readUnsigned();
+ int status;
if (byteValue >= 0x80) {
status = byteValue;
+
+ // update running status (only for channel messages)
+ if ((status & 0xF0) != 0xF0) {
+ runningStatus = status;
+ }
} else {
- data1 = byteValue;
+ status = runningStatus;
+ data1 = byteValue;
}
switch (status & 0xF0) {
diff --git a/src/java.desktop/share/classes/sun/font/FileFontStrike.java b/src/java.desktop/share/classes/sun/font/FileFontStrike.java
index ea2a1608f2d..bf98b8ca578 100644
--- a/src/java.desktop/share/classes/sun/font/FileFontStrike.java
+++ b/src/java.desktop/share/classes/sun/font/FileFontStrike.java
@@ -37,6 +37,7 @@
import java.awt.geom.Rectangle2D;
import java.util.concurrent.ConcurrentHashMap;
import static sun.awt.SunHints.*;
+import sun.java2d.pipe.OutlineTextRenderer;
public class FileFontStrike extends PhysicalStrike {
@@ -107,6 +108,7 @@ public class FileFontStrike extends PhysicalStrike {
boolean useNatives;
NativeStrike[] nativeStrikes;
+ static final int MAX_IMAGE_SIZE = OutlineTextRenderer.THRESHHOLD;
/* Used only for communication to native layer */
private int intPtSize;
@@ -697,6 +699,20 @@ float getCodePointAdvance(int cp) {
void getGlyphImageBounds(int glyphCode, Point2D.Float pt,
Rectangle result) {
+ if (intPtSize > MAX_IMAGE_SIZE) {
+ Rectangle.Float obds = getGlyphOutlineBounds(glyphCode);
+ if (obds.isEmpty()) {
+ Rectangle bds = getGlyphOutline(glyphCode, pt.x, pt.y).getBounds();
+ result.setBounds(bds);
+ } else {
+ result.x = (int)Math.floor(pt.x + obds.getX() + 0.5f);
+ result.y = (int)Math.floor(pt.y + obds.getY() + 0.5f);
+ result.width = (int)Math.floor(obds.getWidth() + 0.5f);
+ result.height = (int)Math.floor(obds.getHeight() + 0.5f);
+ }
+ return;
+ }
+
long ptr = getGlyphImagePtr(glyphCode);
float topLeftX, topLeftY;
diff --git a/src/java.desktop/share/classes/sun/font/HBShaper.java b/src/java.desktop/share/classes/sun/font/HBShaper.java
index 90877623c2b..70e95cdc27b 100644
--- a/src/java.desktop/share/classes/sun/font/HBShaper.java
+++ b/src/java.desktop/share/classes/sun/font/HBShaper.java
@@ -168,22 +168,22 @@ private static VarHandle getVarHandle(StructLayout struct, String name) {
SYM_LOOKUP = SymbolLookup.loaderLookup().or(LINKER.defaultLookup());
FunctionDescriptor mallocDescriptor =
FunctionDescriptor.of(ADDRESS, JAVA_LONG);
- Optional malloc_symbol = SYM_LOOKUP.find("malloc");
+ MemorySegment malloc_symbol = SYM_LOOKUP.findOrThrow("malloc");
@SuppressWarnings("restricted")
- MethodHandle tmp1 = LINKER.downcallHandle(malloc_symbol.get(), mallocDescriptor);
+ MethodHandle tmp1 = LINKER.downcallHandle(malloc_symbol, mallocDescriptor);
malloc_handle = tmp1;
FunctionDescriptor createFaceDescriptor =
FunctionDescriptor.of(ADDRESS, ADDRESS);
- Optional create_face_symbol = SYM_LOOKUP.find("HBCreateFace");
+ MemorySegment create_face_symbol = SYM_LOOKUP.findOrThrow("HBCreateFace");
@SuppressWarnings("restricted")
- MethodHandle tmp2 = LINKER.downcallHandle(create_face_symbol.get(), createFaceDescriptor);
+ MethodHandle tmp2 = LINKER.downcallHandle(create_face_symbol, createFaceDescriptor);
create_face_handle = tmp2;
FunctionDescriptor disposeFaceDescriptor = FunctionDescriptor.ofVoid(ADDRESS);
- Optional dispose_face_symbol = SYM_LOOKUP.find("HBDisposeFace");
+ MemorySegment dispose_face_symbol = SYM_LOOKUP.findOrThrow("HBDisposeFace");
@SuppressWarnings("restricted")
- MethodHandle tmp3 = LINKER.downcallHandle(dispose_face_symbol.get(), disposeFaceDescriptor);
+ MethodHandle tmp3 = LINKER.downcallHandle(dispose_face_symbol, disposeFaceDescriptor);
dispose_face_handle = tmp3;
FunctionDescriptor shapeDesc = FunctionDescriptor.ofVoid(
@@ -204,9 +204,9 @@ private static VarHandle getVarHandle(StructLayout struct, String name) {
ADDRESS, // ptr to harfbuzz font_funcs object.
ADDRESS); // store_results_fn
- Optional shape_sym = SYM_LOOKUP.find("jdk_hb_shape");
+ MemorySegment shape_sym = SYM_LOOKUP.findOrThrow("jdk_hb_shape");
@SuppressWarnings("restricted")
- MethodHandle tmp4 = LINKER.downcallHandle(shape_sym.get(), shapeDesc);
+ MethodHandle tmp4 = LINKER.downcallHandle(shape_sym, shapeDesc);
jdk_hb_shape_handle = tmp4;
Arena garena = Arena.global(); // creating stubs that exist until VM exit.
@@ -260,10 +260,10 @@ private static VarHandle getVarHandle(StructLayout struct, String name) {
ADDRESS, // h_advance_fn upcall stub
ADDRESS, // v_advance_fn upcall stub
ADDRESS); // contour_pt_fn upcall stub
- Optional create_font_funcs_symbol = SYM_LOOKUP.find("HBCreateFontFuncs");
+ MemorySegment create_font_funcs_symbol = SYM_LOOKUP.findOrThrow("HBCreateFontFuncs");
@SuppressWarnings("restricted")
MethodHandle create_font_funcs_handle =
- LINKER.downcallHandle(create_font_funcs_symbol.get(), createFontFuncsDescriptor);
+ LINKER.downcallHandle(create_font_funcs_symbol, createFontFuncsDescriptor);
MemorySegment s = null;
try {
diff --git a/src/java.desktop/share/legal/giflib.md b/src/java.desktop/share/legal/giflib.md
index 0be4fb8226e..8b8fde8706d 100644
--- a/src/java.desktop/share/legal/giflib.md
+++ b/src/java.desktop/share/legal/giflib.md
@@ -1,4 +1,4 @@
-## GIFLIB v5.2.1
+## GIFLIB v5.2.2
### GIFLIB License
```
@@ -24,7 +24,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-https://sourceforge.net/p/giflib/code/ci/master/tree/openbsd-reallocarray.c
+tree/README
-Copyright (c) 2008 Otto Moerbeek
+== Authors ==
+
+Gershon Elber
+original giflib code
+
+Toshio Kuratomi
+uncompressed gif writing code
+former maintainer
+
+Eric Raymond
+current as well as long time former maintainer of giflib code
+
+There have been many other contributors; see the attributions in the
+version-control history to learn more.
+
+
+tree/openbsd-reallocarray.c
+
+Copyright (C) 2008 Otto Moerbeek
SPDX-License-Identifier: MIT
+
+```
diff --git a/src/java.desktop/share/legal/libpng.md b/src/java.desktop/share/legal/libpng.md
index f420ccd94ed..cbffed81332 100644
--- a/src/java.desktop/share/legal/libpng.md
+++ b/src/java.desktop/share/legal/libpng.md
@@ -1,4 +1,4 @@
-## libpng v1.6.40
+## libpng v1.6.43
### libpng License
@@ -9,11 +9,11 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
PNG Reference Library License version 2
---------------------------------------
-Copyright (c) 1995-2023 The PNG Reference Library Authors.
-Copyright (c) 2018-2023 Cosmin Truta
-Copyright (c) 1998-2018 Glenn Randers-Pehrson
-Copyright (c) 1996-1997 Andreas Dilger
-Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+Copyright (C) 1995-2024 The PNG Reference Library Authors.
+Copyright (C) 2018-2024 Cosmin Truta
+Copyright (C) 1998-2018 Glenn Randers-Pehrson
+Copyright (C) 1996-1997 Andreas Dilger
+Copyright (C) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
The software is supplied "as is", without warranty of any kind,
express or implied, including, without limitation, the warranties
@@ -157,7 +157,9 @@ PNG REFERENCE LIBRARY AUTHORS
This is the list of PNG Reference Library ("libpng") Contributing
Authors, for copyright and licensing purposes.
+ * Adam Richter
* Andreas Dilger
+ * Chris Blume
* Cosmin Truta
* Dave Martindale
* Eric S. Raymond
@@ -186,21 +188,28 @@ Authors, for copyright and licensing purposes.
* Vadim Barkov
* Willem van Schaik
* Zhijie Liang
+ * Apple Inc.
+ - Zixu Wang (王子旭)
* Arm Holdings
- - Richard Townsend
+ - Richard Townsend
* Google Inc.
- - Dan Field
- - Leon Scroggins III
- - Matt Sarett
- - Mike Klein
- - Sami Boukortt
- - Wan-Teh Chang
+ - Dan Field
+ - Leon Scroggins III
+ - Matt Sarett
+ - Mike Klein
+ - Sami Boukortt
+ - Wan-Teh Chang
+ * Loongson Technology Corporation Ltd.
+ - GuXiWei (顾希伟)
+ - JinBo (金波)
+ - ZhangLixia (张利霞)
The build projects, the build scripts, the test scripts, and other
-files in the "ci", "projects", "scripts" and "tests" directories, have
+files in the "projects", "scripts" and "tests" directories, have
other copyright owners, but are released under the libpng license.
-Some files in the "contrib" directory, and some tools-generated files
-that are distributed with libpng, have other copyright owners, and are
-released under other open source licenses.
+Some files in the "ci" and "contrib" directories, as well as some
+of the tools-generated files that are distributed with libpng, have
+other copyright owners, and are released under other open source
+licenses.
```
diff --git a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
index 21ac280f0fb..f9ebacad66b 100644
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
@@ -504,6 +504,8 @@ static double euclidianDistance(double a, double b) {
return sqrt(a*a+b*b);
}
+#define TOO_LARGE(a, b) (abs((int)(a / b)) > 32766)
+
JNIEXPORT jlong JNICALL
Java_sun_font_FreetypeFontScaler_createScalerContextNative(
JNIEnv *env, jobject scaler, jlong pScaler, jdoubleArray matrix,
@@ -515,6 +517,7 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
(FTScalerInfo*) jlong_to_ptr(pScaler);
if (context == NULL) {
+ free(context);
invalidateJavaScaler(env, scaler, NULL);
return (jlong) 0;
}
@@ -524,7 +527,18 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
//text can not be smaller than 1 point
ptsz = 1.0;
}
+ if (ptsz > 16384) {
+ ptsz = 16384; // far enough from 32767
+ fm = TEXT_FM_ON; // avoids calculations which might overflow
+ }
context->ptsz = (int)(ptsz * 64);
+ if (TOO_LARGE(dmat[0], ptsz) || TOO_LARGE(dmat[1], ptsz) ||
+ TOO_LARGE(dmat[2], ptsz) || TOO_LARGE(dmat[3], ptsz))
+ {
+ free(context);
+ return (jlong)0;
+ }
+
context->transform.xx = FloatToFTFixed((float)(dmat[0]/ptsz));
context->transform.yx = -FloatToFTFixed((float)(dmat[1]/ptsz));
context->transform.xy = -FloatToFTFixed((float)(dmat[2]/ptsz));
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c b/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c
index 6ddfb46060d..0b2860b4b50 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c
@@ -34,11 +34,11 @@ SPDX-License-Identifier: MIT
*****************************************************************************/
-#include
+#include
#include
#include
-#include
#include
+#include
#include
#ifdef _WIN32
@@ -55,18 +55,19 @@ SPDX-License-Identifier: MIT
/* avoid extra function call in case we use fread (TVT) */
static int InternalRead(GifFileType *gif, GifByteType *buf, int len) {
- //fprintf(stderr, "### Read: %d\n", len);
- return
- (((GifFilePrivateType*)gif->Private)->Read ?
- ((GifFilePrivateType*)gif->Private)->Read(gif,buf,len) :
- fread(buf,1,len,((GifFilePrivateType*)gif->Private)->File));
+ // fprintf(stderr, "### Read: %d\n", len);
+ return (((GifFilePrivateType *)gif->Private)->Read
+ ? ((GifFilePrivateType *)gif->Private)->Read(gif, buf, len)
+ : fread(buf, 1, len,
+ ((GifFilePrivateType *)gif->Private)->File));
}
static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
static int DGifSetupDecompress(GifFileType *GifFile);
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen);
-static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
+static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code,
+ int ClearCode);
static int DGifDecompressInput(GifFileType *GifFile, int *Code);
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
GifByteType *NextByte);
@@ -76,15 +77,14 @@ static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
Returns dynamically allocated GifFileType pointer which serves as the GIF
info record.
******************************************************************************/
-GifFileType *
-DGifOpenFileName(const char *FileName, int *Error)
-{
+GifFileType *DGifOpenFileName(const char *FileName, int *Error) {
int FileHandle;
GifFileType *GifFile;
if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_OPEN_FAILED;
+ }
return NULL;
}
@@ -97,9 +97,7 @@ DGifOpenFileName(const char *FileName, int *Error)
Returns dynamically allocated GifFileType pointer which serves as the GIF
info record.
******************************************************************************/
-GifFileType *
-DGifOpenFileHandle(int FileHandle, int *Error)
-{
+GifFileType *DGifOpenFileHandle(int FileHandle, int *Error) {
char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
@@ -107,13 +105,14 @@ DGifOpenFileHandle(int FileHandle, int *Error)
GifFile = (GifFileType *)malloc(sizeof(GifFileType));
if (GifFile == NULL) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ }
(void)close(FileHandle);
return NULL;
}
- /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
+ /*@i1@*/ memset(GifFile, '\0', sizeof(GifFileType));
/* Belt and suspenders, in case the null pointer isn't zero */
GifFile->SavedImages = NULL;
@@ -121,35 +120,38 @@ DGifOpenFileHandle(int FileHandle, int *Error)
Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (Private == NULL) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ }
(void)close(FileHandle);
free((char *)GifFile);
return NULL;
}
- /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
+ /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType));
#ifdef _WIN32
- _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
-#endif /* _WIN32 */
+ _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
+#endif /* _WIN32 */
- f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
+ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
/*@-mustfreeonly@*/
GifFile->Private = (void *)Private;
Private->FileHandle = FileHandle;
Private->File = f;
Private->FileState = FILE_STATE_READ;
- Private->Read = NULL; /* don't use alternate input method (TVT) */
- GifFile->UserData = NULL; /* TVT */
+ Private->Read = NULL; /* don't use alternate input method (TVT) */
+ GifFile->UserData = NULL; /* TVT */
/*@=mustfreeonly@*/
/* Let's see if this is a GIF file: */
/* coverity[check_return] */
- if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
- if (Error != NULL)
+ if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) !=
+ GIF_STAMP_LEN) {
+ if (Error != NULL) {
*Error = D_GIF_ERR_READ_FAILED;
+ }
(void)fclose(f);
free((char *)Private);
free((char *)GifFile);
@@ -159,8 +161,9 @@ DGifOpenFileHandle(int FileHandle, int *Error)
/* Check for GIF prefix at start of file */
Buf[GIF_STAMP_LEN] = 0;
if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_GIF_FILE;
+ }
(void)fclose(f);
free((char *)Private);
free((char *)GifFile);
@@ -177,7 +180,7 @@ DGifOpenFileHandle(int FileHandle, int *Error)
GifFile->Error = 0;
/* What version of GIF? */
- Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
+ Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9');
return GifFile;
}
@@ -185,17 +188,16 @@ DGifOpenFileHandle(int FileHandle, int *Error)
/******************************************************************************
GifFileType constructor with user supplied input function (TVT)
******************************************************************************/
-GifFileType *
-DGifOpen(void *userData, InputFunc readFunc, int *Error)
-{
+GifFileType *DGifOpen(void *userData, InputFunc readFunc, int *Error) {
char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
GifFile = (GifFileType *)malloc(sizeof(GifFileType));
if (GifFile == NULL) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ }
return NULL;
}
@@ -207,26 +209,29 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (!Private) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ }
free((char *)GifFile);
return NULL;
}
- /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
+ /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType));
GifFile->Private = (void *)Private;
Private->FileHandle = 0;
Private->File = NULL;
Private->FileState = FILE_STATE_READ;
- Private->Read = readFunc; /* TVT */
- GifFile->UserData = userData; /* TVT */
+ Private->Read = readFunc; /* TVT */
+ GifFile->UserData = userData; /* TVT */
/* Lets see if this is a GIF file: */
/* coverity[check_return] */
- if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
- if (Error != NULL)
+ if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) !=
+ GIF_STAMP_LEN) {
+ if (Error != NULL) {
*Error = D_GIF_ERR_READ_FAILED;
+ }
free((char *)Private);
free((char *)GifFile);
return NULL;
@@ -235,8 +240,9 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
/* Check for GIF prefix at start of file */
Buf[GIF_STAMP_LEN] = '\0';
if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NOT_GIF_FILE;
+ }
free((char *)Private);
free((char *)GifFile);
return NULL;
@@ -245,15 +251,16 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
free((char *)Private);
free((char *)GifFile);
- if (Error != NULL)
+ if (Error != NULL) {
*Error = D_GIF_ERR_NO_SCRN_DSCR;
+ }
return NULL;
}
GifFile->Error = 0;
/* What version of GIF? */
- Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
+ Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9');
return GifFile;
}
@@ -262,9 +269,7 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
This routine should be called before any other DGif calls. Note that
this routine is called automatically from DGif file open routines.
******************************************************************************/
-int
-DGifGetScreenDesc(GifFileType *GifFile)
-{
+int DGifGetScreenDesc(GifFileType *GifFile) {
int BitsPerPixel;
bool SortFlag;
GifByteType Buf[3];
@@ -278,8 +283,9 @@ DGifGetScreenDesc(GifFileType *GifFile)
/* Put the screen descriptor into the file: */
if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
- DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
+ DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) {
return GIF_ERROR;
+ }
if (InternalRead(GifFile, Buf, 3) != 3) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
@@ -292,7 +298,7 @@ DGifGetScreenDesc(GifFileType *GifFile)
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
GifFile->AspectByte = Buf[2];
- if (Buf[0] & 0x80) { /* Do we have global color map? */
+ if (Buf[0] & 0x80) { /* Do we have global color map? */
int i;
GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
@@ -327,23 +333,20 @@ DGifGetScreenDesc(GifFileType *GifFile)
return GIF_OK;
}
-const char *
-DGifGetGifVersion(GifFileType *GifFile)
-{
- GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
+const char *DGifGetGifVersion(GifFileType *GifFile) {
+ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
- if (Private->gif89)
+ if (Private->gif89) {
return GIF89_STAMP;
- else
+ } else {
return GIF87_STAMP;
+ }
}
/******************************************************************************
This routine should be called before any attempt to read an image.
******************************************************************************/
-int
-DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
-{
+int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
@@ -359,29 +362,27 @@ DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
return GIF_ERROR;
}
- //fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
+ // fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
switch (Buf) {
- case DESCRIPTOR_INTRODUCER:
- *Type = IMAGE_DESC_RECORD_TYPE;
- break;
- case EXTENSION_INTRODUCER:
- *Type = EXTENSION_RECORD_TYPE;
- break;
- case TERMINATOR_INTRODUCER:
- *Type = TERMINATE_RECORD_TYPE;
- break;
- default:
- *Type = UNDEFINED_RECORD_TYPE;
- GifFile->Error = D_GIF_ERR_WRONG_RECORD;
- return GIF_ERROR;
+ case DESCRIPTOR_INTRODUCER:
+ *Type = IMAGE_DESC_RECORD_TYPE;
+ break;
+ case EXTENSION_INTRODUCER:
+ *Type = EXTENSION_RECORD_TYPE;
+ break;
+ case TERMINATOR_INTRODUCER:
+ *Type = TERMINATE_RECORD_TYPE;
+ break;
+ default:
+ *Type = UNDEFINED_RECORD_TYPE;
+ GifFile->Error = D_GIF_ERR_WRONG_RECORD;
+ return GIF_ERROR;
}
return GIF_OK;
}
-int
-DGifGetImageHeader(GifFileType *GifFile)
-{
+int DGifGetImageHeader(GifFileType *GifFile) {
unsigned int BitsPerPixel;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
@@ -395,8 +396,9 @@ DGifGetImageHeader(GifFileType *GifFile)
if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
- DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
+ DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) {
return GIF_ERROR;
+ }
if (InternalRead(GifFile, Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
GifFreeMapObject(GifFile->Image.ColorMap);
@@ -415,7 +417,8 @@ DGifGetImageHeader(GifFileType *GifFile)
if (Buf[0] & 0x80) {
unsigned int i;
- GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
+ GifFile->Image.ColorMap =
+ GifMakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->Image.ColorMap == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
@@ -436,8 +439,8 @@ DGifGetImageHeader(GifFileType *GifFile)
}
}
- Private->PixelCount = (long)GifFile->Image.Width *
- (long)GifFile->Image.Height;
+ Private->PixelCount =
+ (long)GifFile->Image.Width * (long)GifFile->Image.Height;
/* Reset decompress algorithm parameters. */
return DGifSetupDecompress(GifFile);
@@ -447,9 +450,7 @@ DGifGetImageHeader(GifFileType *GifFile)
This routine should be called before any attempt to read an image.
Note it is assumed the Image desc. header has been read.
******************************************************************************/
-int
-DGifGetImageDesc(GifFileType *GifFile)
-{
+int DGifGetImageDesc(GifFileType *GifFile) {
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
SavedImage *sp;
@@ -464,9 +465,9 @@ DGifGetImageDesc(GifFileType *GifFile)
}
if (GifFile->SavedImages) {
- SavedImage* new_saved_images =
- (SavedImage *)reallocarray(GifFile->SavedImages,
- (GifFile->ImageCount + 1), sizeof(SavedImage));
+ SavedImage *new_saved_images = (SavedImage *)reallocarray(
+ GifFile->SavedImages, (GifFile->ImageCount + 1),
+ sizeof(SavedImage));
if (new_saved_images == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
@@ -474,7 +475,7 @@ DGifGetImageDesc(GifFileType *GifFile)
GifFile->SavedImages = new_saved_images;
} else {
if ((GifFile->SavedImages =
- (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
+ (SavedImage *)malloc(sizeof(SavedImage))) == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
@@ -483,9 +484,9 @@ DGifGetImageDesc(GifFileType *GifFile)
sp = &GifFile->SavedImages[GifFile->ImageCount];
memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
if (GifFile->Image.ColorMap != NULL) {
- sp->ImageDesc.ColorMap = GifMakeMapObject(
- GifFile->Image.ColorMap->ColorCount,
- GifFile->Image.ColorMap->Colors);
+ sp->ImageDesc.ColorMap =
+ GifMakeMapObject(GifFile->Image.ColorMap->ColorCount,
+ GifFile->Image.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
@@ -493,7 +494,7 @@ DGifGetImageDesc(GifFileType *GifFile)
}
sp->RasterBits = (unsigned char *)NULL;
sp->ExtensionBlockCount = 0;
- sp->ExtensionBlocks = (ExtensionBlock *) NULL;
+ sp->ExtensionBlocks = (ExtensionBlock *)NULL;
GifFile->ImageCount++;
@@ -503,11 +504,9 @@ DGifGetImageDesc(GifFileType *GifFile)
/******************************************************************************
Get one full scanned line (Line) of length LineLen from GIF file.
******************************************************************************/
-int
-DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
-{
+int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) {
GifByteType *Dummy;
- GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
+ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
@@ -515,8 +514,9 @@ DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
return GIF_ERROR;
}
- if (!LineLen)
+ if (!LineLen) {
LineLen = GifFile->Image.Width;
+ }
if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
@@ -525,56 +525,59 @@ DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
if (Private->PixelCount == 0) {
- /* We probably won't be called any more, so let's clean up
- * everything before we return: need to flush out all the
- * rest of image until an empty block (size 0)
+ /* We probably won't be called any more, so let's clean
+ * up everything before we return: need to flush out all
+ * the rest of image until an empty block (size 0)
* detected. We use GetCodeNext.
*/
- do
- if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
+ do {
+ if (DGifGetCodeNext(GifFile, &Dummy) ==
+ GIF_ERROR) {
return GIF_ERROR;
- while (Dummy != NULL) ;
+ }
+ } while (Dummy != NULL);
}
return GIF_OK;
- } else
+ } else {
return GIF_ERROR;
+ }
}
/******************************************************************************
Put one pixel (Pixel) into GIF file.
******************************************************************************/
-int
-DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
-{
+int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel) {
GifByteType *Dummy;
- GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
+ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
- if (--Private->PixelCount > 0xffff0000UL)
- {
+ if (--Private->PixelCount > 0xffff0000UL) {
GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
if (Private->PixelCount == 0) {
- /* We probably won't be called any more, so let's clean up
- * everything before we return: need to flush out all the
- * rest of image until an empty block (size 0)
+ /* We probably won't be called any more, so let's clean
+ * up everything before we return: need to flush out all
+ * the rest of image until an empty block (size 0)
* detected. We use GetCodeNext.
*/
- do
- if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
+ do {
+ if (DGifGetCodeNext(GifFile, &Dummy) ==
+ GIF_ERROR) {
return GIF_ERROR;
- while (Dummy != NULL) ;
+ }
+ } while (Dummy != NULL);
}
return GIF_OK;
- } else
+ } else {
return GIF_ERROR;
+ }
}
/******************************************************************************
@@ -584,13 +587,12 @@ DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
The Extension should NOT be freed by the user (not dynamically allocated).
Note it is assumed the Extension description header has been read.
******************************************************************************/
-int
-DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
-{
+int DGifGetExtension(GifFileType *GifFile, int *ExtCode,
+ GifByteType **Extension) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
- //fprintf(stderr, "### -> DGifGetExtension:\n");
+ // fprintf(stderr, "### -> DGifGetExtension:\n");
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
GifFile->Error = D_GIF_ERR_NOT_READABLE;
@@ -603,7 +605,8 @@ DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
return GIF_ERROR;
}
*ExtCode = Buf;
- //fprintf(stderr, "### <- DGifGetExtension: %02x, about to call next\n", Buf);
+ // fprintf(stderr, "### <- DGifGetExtension: %02x, about to call
+ // next\n", Buf);
return DGifGetExtensionNext(GifFile, Extension);
}
@@ -613,30 +616,30 @@ DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
routine should be called until NULL Extension is returned.
The Extension should NOT be freed by the user (not dynamically allocated).
******************************************************************************/
-int
-DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
-{
+int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
- //fprintf(stderr, "### -> DGifGetExtensionNext\n");
+ // fprintf(stderr, "### -> DGifGetExtensionNext\n");
if (InternalRead(GifFile, &Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
- //fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
+ // fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
if (Buf > 0) {
- *Extension = Private->Buf; /* Use private unused buffer. */
- (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
- /* coverity[tainted_data,check_return] */
+ *Extension = Private->Buf; /* Use private unused buffer. */
+ (*Extension)[0] =
+ Buf; /* Pascal strings notation (pos. 0 is len.). */
+ /* coverity[tainted_data,check_return] */
if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
- } else
+ } else {
*Extension = NULL;
- //fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
+ }
+ // fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
return GIF_OK;
}
@@ -647,19 +650,20 @@ DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
int DGifExtensionToGCB(const size_t GifExtensionLength,
const GifByteType *GifExtension,
- GraphicsControlBlock *GCB)
-{
+ GraphicsControlBlock *GCB) {
if (GifExtensionLength != 4) {
return GIF_ERROR;
}
GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
- GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
- if (GifExtension[0] & 0x01)
+ GCB->DelayTime =
+ UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
+ if (GifExtension[0] & 0x01) {
GCB->TransparentColor = (int)GifExtension[3];
- else
+ } else {
GCB->TransparentColor = NO_TRANSPARENT_COLOR;
+ }
return GIF_OK;
}
@@ -668,23 +672,27 @@ int DGifExtensionToGCB(const size_t GifExtensionLength,
Extract the Graphics Control Block for a saved image, if it exists.
******************************************************************************/
-int DGifSavedExtensionToGCB(GifFileType *GifFile,
- int ImageIndex, GraphicsControlBlock *GCB)
-{
+int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex,
+ GraphicsControlBlock *GCB) {
int i;
- if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
+ if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) {
return GIF_ERROR;
+ }
GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
GCB->UserInputFlag = false;
GCB->DelayTime = 0;
GCB->TransparentColor = NO_TRANSPARENT_COLOR;
- for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
- ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
- if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
- return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
+ for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount;
+ i++) {
+ ExtensionBlock *ep =
+ &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
+ if (ep->Function == GRAPHICS_EXT_FUNC_CODE) {
+ return DGifExtensionToGCB(ep->ByteCount, ep->Bytes,
+ GCB);
+ }
}
return GIF_ERROR;
@@ -693,13 +701,12 @@ int DGifSavedExtensionToGCB(GifFileType *GifFile,
/******************************************************************************
This routine should be called last, to close the GIF file.
******************************************************************************/
-int
-DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
-{
+int DGifCloseFile(GifFileType *GifFile, int *ErrorCode) {
GifFilePrivateType *Private;
- if (GifFile == NULL || GifFile->Private == NULL)
+ if (GifFile == NULL || GifFile->Private == NULL) {
return GIF_ERROR;
+ }
if (GifFile->Image.ColorMap) {
GifFreeMapObject(GifFile->Image.ColorMap);
@@ -716,22 +723,25 @@ DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
GifFile->SavedImages = NULL;
}
- GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
+ GifFreeExtensions(&GifFile->ExtensionBlockCount,
+ &GifFile->ExtensionBlocks);
- Private = (GifFilePrivateType *) GifFile->Private;
+ Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- if (ErrorCode != NULL)
+ if (ErrorCode != NULL) {
*ErrorCode = D_GIF_ERR_NOT_READABLE;
+ }
free((char *)GifFile->Private);
free(GifFile);
return GIF_ERROR;
}
if (Private->File && (fclose(Private->File) != 0)) {
- if (ErrorCode != NULL)
+ if (ErrorCode != NULL) {
*ErrorCode = D_GIF_ERR_CLOSE_FAILED;
+ }
free((char *)GifFile->Private);
free(GifFile);
return GIF_ERROR;
@@ -739,17 +749,16 @@ DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
free((char *)GifFile->Private);
free(GifFile);
- if (ErrorCode != NULL)
+ if (ErrorCode != NULL) {
*ErrorCode = D_GIF_SUCCEEDED;
+ }
return GIF_OK;
}
/******************************************************************************
Get 2 bytes (word) from the given file:
******************************************************************************/
-static int
-DGifGetWord(GifFileType *GifFile, GifWord *Word)
-{
+static int DGifGetWord(GifFileType *GifFile, GifWord *Word) {
unsigned char c[2];
/* coverity[check_return] */
@@ -769,9 +778,7 @@ DGifGetWord(GifFileType *GifFile, GifWord *Word)
to DGifGetCodeNext, until NULL block is returned.
The block should NOT be freed by the user (not dynamically allocated).
******************************************************************************/
-int
-DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
-{
+int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock) {
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
@@ -790,9 +797,7 @@ DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
called until NULL block is returned.
The block should NOT be freed by the user (not dynamically allocated).
******************************************************************************/
-int
-DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
-{
+int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
@@ -805,17 +810,19 @@ DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
/* coverity[lower_bounds] */
if (Buf > 0) {
- *CodeBlock = Private->Buf; /* Use private unused buffer. */
- (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
- /* coverity[tainted_data] */
+ *CodeBlock = Private->Buf; /* Use private unused buffer. */
+ (*CodeBlock)[0] =
+ Buf; /* Pascal strings notation (pos. 0 is len.). */
+ /* coverity[tainted_data] */
if (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
} else {
*CodeBlock = NULL;
- Private->Buf[0] = 0; /* Make sure the buffer is empty! */
- Private->PixelCount = 0; /* And local info. indicate image read. */
+ Private->Buf[0] = 0; /* Make sure the buffer is empty! */
+ Private->PixelCount =
+ 0; /* And local info. indicate image read. */
}
return GIF_OK;
@@ -824,41 +831,43 @@ DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
/******************************************************************************
Setup the LZ decompression for this image:
******************************************************************************/
-static int
-DGifSetupDecompress(GifFileType *GifFile)
-{
+static int DGifSetupDecompress(GifFileType *GifFile) {
int i, BitsPerPixel;
GifByteType CodeSize;
GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
/* coverity[check_return] */
- if (InternalRead(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
- return GIF_ERROR; /* Failed to read Code size. */
+ if (InternalRead(GifFile, &CodeSize, 1) <
+ 1) { /* Read Code size from file. */
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ return GIF_ERROR; /* Failed to read Code size. */
}
BitsPerPixel = CodeSize;
/* this can only happen on a severely malformed GIF */
if (BitsPerPixel > 8) {
- GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
- return GIF_ERROR; /* Failed to read Code size. */
+ GifFile->Error =
+ D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
+ return GIF_ERROR; /* Failed to read Code size. */
}
- Private->Buf[0] = 0; /* Input Buffer empty. */
+ Private->Buf[0] = 0; /* Input Buffer empty. */
Private->BitsPerPixel = BitsPerPixel;
Private->ClearCode = (1 << BitsPerPixel);
Private->EOFCode = Private->ClearCode + 1;
Private->RunningCode = Private->EOFCode + 1;
- Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
- Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
- Private->StackPtr = 0; /* No pixels on the pixel stack. */
+ Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
+ Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
+ Private->StackPtr = 0; /* No pixels on the pixel stack. */
Private->LastCode = NO_SUCH_CODE;
- Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
+ Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
Private->CrntShiftDWord = 0;
Prefix = Private->Prefix;
- for (i = 0; i <= LZ_MAX_CODE; i++)
+ for (i = 0; i <= LZ_MAX_CODE; i++) {
Prefix[i] = NO_SUCH_CODE;
+ }
return GIF_OK;
}
@@ -869,14 +878,13 @@ DGifSetupDecompress(GifFileType *GifFile)
This routine can be called few times (one per scan line, for example), in
order the complete the whole image.
******************************************************************************/
-static int
-DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
-{
+static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
+ int LineLen) {
int i = 0;
int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
GifByteType *Stack, *Suffix;
GifPrefixType *Prefix;
- GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
+ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
StackPtr = Private->StackPtr;
Prefix = Private->Prefix;
@@ -891,72 +899,88 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
}
if (StackPtr != 0) {
- /* Let pop the stack off before continueing to read the GIF file: */
- while (StackPtr != 0 && i < LineLen)
+ /* Let pop the stack off before continueing to read the GIF
+ * file: */
+ while (StackPtr != 0 && i < LineLen) {
Line[i++] = Stack[--StackPtr];
+ }
}
- while (i < LineLen) { /* Decode LineLen items. */
- if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
+ while (i < LineLen) { /* Decode LineLen items. */
+ if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) {
return GIF_ERROR;
+ }
if (CrntCode == EOFCode) {
- /* Note however that usually we will not be here as we will stop
- * decoding as soon as we got all the pixel, or EOF code will
- * not be read at all, and DGifGetLine/Pixel clean everything. */
+ /* Note however that usually we will not be here as we
+ * will stop decoding as soon as we got all the pixel,
+ * or EOF code will not be read at all, and
+ * DGifGetLine/Pixel clean everything. */
GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
return GIF_ERROR;
} else if (CrntCode == ClearCode) {
/* We need to start over again: */
- for (j = 0; j <= LZ_MAX_CODE; j++)
+ for (j = 0; j <= LZ_MAX_CODE; j++) {
Prefix[j] = NO_SUCH_CODE;
+ }
Private->RunningCode = Private->EOFCode + 1;
Private->RunningBits = Private->BitsPerPixel + 1;
Private->MaxCode1 = 1 << Private->RunningBits;
LastCode = Private->LastCode = NO_SUCH_CODE;
} else {
- /* Its regular code - if in pixel range simply add it to output
- * stream, otherwise trace to codes linked list until the prefix
- * is in pixel range: */
+ /* Its regular code - if in pixel range simply add it to
+ * output stream, otherwise trace to codes linked list
+ * until the prefix is in pixel range: */
if (CrntCode < ClearCode) {
- /* This is simple - its pixel scalar, so add it to output: */
+ /* This is simple - its pixel scalar, so add it
+ * to output: */
Line[i++] = CrntCode;
} else {
- /* Its a code to needed to be traced: trace the linked list
- * until the prefix is a pixel, while pushing the suffix
- * pixels on our stack. If we done, pop the stack in reverse
- * (thats what stack is good for!) order to output. */
+ /* Its a code to needed to be traced: trace the
+ * linked list until the prefix is a pixel,
+ * while pushing the suffix pixels on our stack.
+ * If we done, pop the stack in reverse (thats
+ * what stack is good for!) order to output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
CrntPrefix = LastCode;
- /* Only allowed if CrntCode is exactly the running code:
- * In that case CrntCode = XXXCode, CrntCode or the
- * prefix code is last code and the suffix char is
- * exactly the prefix of last code! */
- if (CrntCode == Private->RunningCode - 2) {
- Suffix[Private->RunningCode - 2] =
- Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
- LastCode,
- ClearCode);
+ /* Only allowed if CrntCode is exactly
+ * the running code: In that case
+ * CrntCode = XXXCode, CrntCode or the
+ * prefix code is last code and the
+ * suffix char is exactly the prefix of
+ * last code! */
+ if (CrntCode ==
+ Private->RunningCode - 2) {
+ Suffix[Private->RunningCode -
+ 2] = Stack[StackPtr++] =
+ DGifGetPrefixChar(
+ Prefix, LastCode,
+ ClearCode);
} else {
- Suffix[Private->RunningCode - 2] =
- Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
- CrntCode,
- ClearCode);
+ Suffix[Private->RunningCode -
+ 2] = Stack[StackPtr++] =
+ DGifGetPrefixChar(
+ Prefix, CrntCode,
+ ClearCode);
}
- } else
+ } else {
CrntPrefix = CrntCode;
+ }
- /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
- * during the trace. As we might loop forever, in case of
- * defective image, we use StackPtr as loop counter and stop
- * before overflowing Stack[]. */
+ /* Now (if image is O.K.) we should not get a
+ * NO_SUCH_CODE during the trace. As we might
+ * loop forever, in case of defective image, we
+ * use StackPtr as loop counter and stop before
+ * overflowing Stack[]. */
while (StackPtr < LZ_MAX_CODE &&
- CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
+ CrntPrefix > ClearCode &&
+ CrntPrefix <= LZ_MAX_CODE) {
Stack[StackPtr++] = Suffix[CrntPrefix];
CrntPrefix = Prefix[CrntPrefix];
}
- if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
+ if (StackPtr >= LZ_MAX_CODE ||
+ CrntPrefix > LZ_MAX_CODE) {
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
@@ -964,22 +988,29 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
Stack[StackPtr++] = CrntPrefix;
/* Now lets pop all the stack into output: */
- while (StackPtr != 0 && i < LineLen)
+ while (StackPtr != 0 && i < LineLen) {
Line[i++] = Stack[--StackPtr];
+ }
}
- if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < (LZ_MAX_CODE+1) && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
+ if (LastCode != NO_SUCH_CODE &&
+ Private->RunningCode - 2 < (LZ_MAX_CODE + 1) &&
+ Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
Prefix[Private->RunningCode - 2] = LastCode;
if (CrntCode == Private->RunningCode - 2) {
- /* Only allowed if CrntCode is exactly the running code:
- * In that case CrntCode = XXXCode, CrntCode or the
- * prefix code is last code and the suffix char is
- * exactly the prefix of last code! */
+ /* Only allowed if CrntCode is exactly
+ * the running code: In that case
+ * CrntCode = XXXCode, CrntCode or the
+ * prefix code is last code and the
+ * suffix char is exactly the prefix of
+ * last code! */
Suffix[Private->RunningCode - 2] =
- DGifGetPrefixChar(Prefix, LastCode, ClearCode);
+ DGifGetPrefixChar(Prefix, LastCode,
+ ClearCode);
} else {
Suffix[Private->RunningCode - 2] =
- DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
+ DGifGetPrefixChar(Prefix, CrntCode,
+ ClearCode);
}
}
LastCode = CrntCode;
@@ -998,9 +1029,8 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
If image is defective, we might loop here forever, so we limit the loops to
the maximum possible if image O.k. - LZ_MAX_CODE times.
******************************************************************************/
-static int
-DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
-{
+static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code,
+ int ClearCode) {
int i = 0;
while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
@@ -1016,9 +1046,7 @@ DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
Interface for accessing the LZ codes directly. Set Code to the real code
(12bits), or to -1 if EOF code is returned.
******************************************************************************/
-int
-DGifGetLZCodes(GifFileType *GifFile, int *Code)
-{
+int DGifGetLZCodes(GifFileType *GifFile, int *Code) {
GifByteType *CodeBlock;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
@@ -1028,15 +1056,18 @@ DGifGetLZCodes(GifFileType *GifFile, int *Code)
return GIF_ERROR;
}
- if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
+ if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) {
return GIF_ERROR;
+ }
if (*Code == Private->EOFCode) {
- /* Skip rest of codes (hopefully only NULL terminating block): */
+ /* Skip rest of codes (hopefully only NULL terminating block):
+ */
do {
- if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
+ if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
return GIF_ERROR;
- } while (CodeBlock != NULL) ;
+ }
+ } while (CodeBlock != NULL);
*Code = -1;
} else if (*Code == Private->ClearCode) {
@@ -1055,15 +1086,10 @@ DGifGetLZCodes(GifFileType *GifFile, int *Code)
8 bits (bytes) packets, into the real codes.
Returns GIF_OK if read successfully.
******************************************************************************/
-static int
-DGifDecompressInput(GifFileType *GifFile, int *Code)
-{
+static int DGifDecompressInput(GifFileType *GifFile, int *Code) {
static const unsigned short CodeMasks[] = {
- 0x0000, 0x0001, 0x0003, 0x0007,
- 0x000f, 0x001f, 0x003f, 0x007f,
- 0x00ff, 0x01ff, 0x03ff, 0x07ff,
- 0x0fff
- };
+ 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f,
+ 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff};
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
@@ -1077,11 +1103,12 @@ DGifDecompressInput(GifFileType *GifFile, int *Code)
while (Private->CrntShiftState < Private->RunningBits) {
/* Needs to get more bytes from input stream for next code: */
- if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
+ if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) ==
+ GIF_ERROR) {
return GIF_ERROR;
}
- Private->CrntShiftDWord |=
- ((unsigned long)NextByte) << Private->CrntShiftState;
+ Private->CrntShiftDWord |= ((unsigned long)NextByte)
+ << Private->CrntShiftState;
Private->CrntShiftState += 8;
}
*Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
@@ -1109,9 +1136,8 @@ DGifDecompressInput(GifFileType *GifFile, int *Code)
The routine returns the next byte from its internal buffer (or read next
block in if buffer empty) and returns GIF_OK if succesful.
******************************************************************************/
-static int
-DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
-{
+static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
+ GifByteType *NextByte) {
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
/* coverity[check_return] */
@@ -1120,8 +1146,8 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
return GIF_ERROR;
}
/* There shouldn't be any empty data blocks here as the LZW spec
- * says the LZW termination code should come first. Therefore we
- * shouldn't be inside this routine at that point.
+ * says the LZW termination code should come first. Therefore
+ * we shouldn't be inside this routine at that point.
*/
if (Buf[0] == 0) {
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
@@ -1132,7 +1158,7 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
return GIF_ERROR;
}
*NextByte = Buf[1];
- Buf[1] = 2; /* We use now the second place as last char read! */
+ Buf[1] = 2; /* We use now the second place as last char read! */
Buf[0]--;
} else {
*NextByte = Buf[Buf[1]++];
@@ -1142,14 +1168,32 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
return GIF_OK;
}
+/******************************************************************************
+ This routine is called in case of error during parsing image. We need to
+ decrease image counter and reallocate memory for saved images. Not decreasing
+ ImageCount may lead to null pointer dereference, because the last element in
+ SavedImages may point to the spoilt image and null pointer buffers.
+*******************************************************************************/
+void DGifDecreaseImageCounter(GifFileType *GifFile) {
+ GifFile->ImageCount--;
+ if (GifFile->SavedImages[GifFile->ImageCount].RasterBits != NULL) {
+ free(GifFile->SavedImages[GifFile->ImageCount].RasterBits);
+ }
+
+ // Realloc array according to the new image counter.
+ SavedImage *correct_saved_images = (SavedImage *)reallocarray(
+ GifFile->SavedImages, GifFile->ImageCount, sizeof(SavedImage));
+ if (correct_saved_images != NULL) {
+ GifFile->SavedImages = correct_saved_images;
+ }
+}
+
/******************************************************************************
This routine reads an entire GIF into core, hanging all its state info off
the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
first to initialize I/O. Its inverse is EGifSpew().
*******************************************************************************/
-int
-DGifSlurp(GifFileType *GifFile)
-{
+int DGifSlurp(GifFileType *GifFile) {
size_t ImageSize;
GifRecordType RecordType;
SavedImage *sp;
@@ -1160,103 +1204,130 @@ DGifSlurp(GifFileType *GifFile)
GifFile->ExtensionBlockCount = 0;
do {
- if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
+ if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
return (GIF_ERROR);
+ }
switch (RecordType) {
- case IMAGE_DESC_RECORD_TYPE:
- if (DGifGetImageDesc(GifFile) == GIF_ERROR)
- return (GIF_ERROR);
-
- sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
- /* Allocate memory for the image */
- if (sp->ImageDesc.Width <= 0 || sp->ImageDesc.Height <= 0 ||
- sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
- return GIF_ERROR;
- }
- ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
-
- if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
- return GIF_ERROR;
- }
- sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
- sizeof(GifPixelType));
-
- if (sp->RasterBits == NULL) {
- return GIF_ERROR;
- }
-
- if (sp->ImageDesc.Interlace) {
- int i, j;
- /*
- * The way an interlaced image should be read -
- * offsets and jumps...
- */
- int InterlacedOffset[] = { 0, 4, 2, 1 };
- int InterlacedJumps[] = { 8, 8, 4, 2 };
- /* Need to perform 4 passes on the image */
- for (i = 0; i < 4; i++)
- for (j = InterlacedOffset[i];
- j < sp->ImageDesc.Height;
- j += InterlacedJumps[i]) {
- if (DGifGetLine(GifFile,
- sp->RasterBits+j*sp->ImageDesc.Width,
- sp->ImageDesc.Width) == GIF_ERROR)
- return GIF_ERROR;
- }
- }
- else {
- if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
- return (GIF_ERROR);
- }
-
- if (GifFile->ExtensionBlocks) {
- sp->ExtensionBlocks = GifFile->ExtensionBlocks;
- sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
-
- GifFile->ExtensionBlocks = NULL;
- GifFile->ExtensionBlockCount = 0;
- }
- break;
-
- case EXTENSION_RECORD_TYPE:
- if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
- return (GIF_ERROR);
- /* Create an extension block with our data */
- if (ExtData != NULL) {
- if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
- &GifFile->ExtensionBlocks,
- ExtFunction, ExtData[0], &ExtData[1])
- == GIF_ERROR)
- return (GIF_ERROR);
- }
- for (;;) {
- if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
- return (GIF_ERROR);
- if (ExtData == NULL)
- break;
- /* Continue the extension block */
- if (ExtData != NULL)
- if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
- &GifFile->ExtensionBlocks,
- CONTINUE_EXT_FUNC_CODE,
- ExtData[0], &ExtData[1]) == GIF_ERROR)
- return (GIF_ERROR);
- }
- break;
-
- case TERMINATE_RECORD_TYPE:
- break;
-
- default: /* Should be trapped by DGifGetRecordType */
- break;
+ case IMAGE_DESC_RECORD_TYPE:
+ if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
+ return (GIF_ERROR);
+ }
+
+ sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
+ /* Allocate memory for the image */
+ if (sp->ImageDesc.Width <= 0 ||
+ sp->ImageDesc.Height <= 0 ||
+ sp->ImageDesc.Width >
+ (INT_MAX / sp->ImageDesc.Height)) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
+ ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
+
+ if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
+ sp->RasterBits = (unsigned char *)reallocarray(
+ NULL, ImageSize, sizeof(GifPixelType));
+
+ if (sp->RasterBits == NULL) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
+
+ if (sp->ImageDesc.Interlace) {
+ int i, j;
+ /*
+ * The way an interlaced image should be read -
+ * offsets and jumps...
+ */
+ static const int InterlacedOffset[] = {0, 4, 2,
+ 1};
+ static const int InterlacedJumps[] = {8, 8, 4,
+ 2};
+ /* Need to perform 4 passes on the image */
+ for (i = 0; i < 4; i++) {
+ for (j = InterlacedOffset[i];
+ j < sp->ImageDesc.Height;
+ j += InterlacedJumps[i]) {
+ if (DGifGetLine(
+ GifFile,
+ sp->RasterBits +
+ j * sp->ImageDesc
+ .Width,
+ sp->ImageDesc.Width) ==
+ GIF_ERROR) {
+ DGifDecreaseImageCounter(
+ GifFile);
+ return GIF_ERROR;
+ }
+ }
+ }
+ } else {
+ if (DGifGetLine(GifFile, sp->RasterBits,
+ ImageSize) == GIF_ERROR) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
+ }
+
+ if (GifFile->ExtensionBlocks) {
+ sp->ExtensionBlocks = GifFile->ExtensionBlocks;
+ sp->ExtensionBlockCount =
+ GifFile->ExtensionBlockCount;
+
+ GifFile->ExtensionBlocks = NULL;
+ GifFile->ExtensionBlockCount = 0;
+ }
+ break;
+
+ case EXTENSION_RECORD_TYPE:
+ if (DGifGetExtension(GifFile, &ExtFunction, &ExtData) ==
+ GIF_ERROR) {
+ return (GIF_ERROR);
+ }
+ /* Create an extension block with our data */
+ if (ExtData != NULL) {
+ if (GifAddExtensionBlock(
+ &GifFile->ExtensionBlockCount,
+ &GifFile->ExtensionBlocks, ExtFunction,
+ ExtData[0], &ExtData[1]) == GIF_ERROR) {
+ return (GIF_ERROR);
+ }
+ }
+ for (;;) {
+ if (DGifGetExtensionNext(GifFile, &ExtData) ==
+ GIF_ERROR) {
+ return (GIF_ERROR);
+ }
+ if (ExtData == NULL) {
+ break;
+ }
+ /* Continue the extension block */
+ if (GifAddExtensionBlock(
+ &GifFile->ExtensionBlockCount,
+ &GifFile->ExtensionBlocks,
+ CONTINUE_EXT_FUNC_CODE, ExtData[0],
+ &ExtData[1]) == GIF_ERROR) {
+ return (GIF_ERROR);
+ }
+ }
+ break;
+
+ case TERMINATE_RECORD_TYPE:
+ break;
+
+ default: /* Should be trapped by DGifGetRecordType */
+ break;
}
} while (RecordType != TERMINATE_RECORD_TYPE);
/* Sanity check for corrupted file */
if (GifFile->ImageCount == 0) {
GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
- return(GIF_ERROR);
+ return (GIF_ERROR);
}
return (GIF_OK);
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c b/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c
index db08838efff..3b6785f7c63 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c
@@ -38,82 +38,80 @@ SPDX-License-Identifier: MIT
/*****************************************************************************
Return a string description of the last GIF error
*****************************************************************************/
-const char *
-GifErrorString(int ErrorCode)
-{
+const char *GifErrorString(int ErrorCode) {
const char *Err;
switch (ErrorCode) {
- case E_GIF_ERR_OPEN_FAILED:
+ case E_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
- case E_GIF_ERR_WRITE_FAILED:
+ case E_GIF_ERR_WRITE_FAILED:
Err = "Failed to write to given file";
break;
- case E_GIF_ERR_HAS_SCRN_DSCR:
+ case E_GIF_ERR_HAS_SCRN_DSCR:
Err = "Screen descriptor has already been set";
break;
- case E_GIF_ERR_HAS_IMAG_DSCR:
+ case E_GIF_ERR_HAS_IMAG_DSCR:
Err = "Image descriptor is still active";
break;
- case E_GIF_ERR_NO_COLOR_MAP:
+ case E_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
- case E_GIF_ERR_DATA_TOO_BIG:
+ case E_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
- case E_GIF_ERR_NOT_ENOUGH_MEM:
+ case E_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
- case E_GIF_ERR_DISK_IS_FULL:
+ case E_GIF_ERR_DISK_IS_FULL:
Err = "Write failed (disk full?)";
break;
- case E_GIF_ERR_CLOSE_FAILED:
+ case E_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
- case E_GIF_ERR_NOT_WRITEABLE:
+ case E_GIF_ERR_NOT_WRITEABLE:
Err = "Given file was not opened for write";
break;
- case D_GIF_ERR_OPEN_FAILED:
+ case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
- case D_GIF_ERR_READ_FAILED:
+ case D_GIF_ERR_READ_FAILED:
Err = "Failed to read from given file";
break;
- case D_GIF_ERR_NOT_GIF_FILE:
+ case D_GIF_ERR_NOT_GIF_FILE:
Err = "Data is not in GIF format";
break;
- case D_GIF_ERR_NO_SCRN_DSCR:
+ case D_GIF_ERR_NO_SCRN_DSCR:
Err = "No screen descriptor detected";
break;
- case D_GIF_ERR_NO_IMAG_DSCR:
+ case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
- case D_GIF_ERR_NO_COLOR_MAP:
+ case D_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
- case D_GIF_ERR_WRONG_RECORD:
+ case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
- case D_GIF_ERR_DATA_TOO_BIG:
+ case D_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
- case D_GIF_ERR_NOT_ENOUGH_MEM:
+ case D_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
- case D_GIF_ERR_CLOSE_FAILED:
+ case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
- case D_GIF_ERR_NOT_READABLE:
+ case D_GIF_ERR_NOT_READABLE:
Err = "Given file was not opened for read";
break;
- case D_GIF_ERR_IMAGE_DEFECT:
+ case D_GIF_ERR_IMAGE_DEFECT:
Err = "Image is defective, decoding aborted";
break;
- case D_GIF_ERR_EOF_TOO_SOON:
+ case D_GIF_ERR_EOF_TOO_SOON:
Err = "Image EOF detected before image complete";
break;
- default:
+ default:
Err = NULL;
break;
}
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h b/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h
index 6cabd0866ed..bd00af64161 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h
@@ -33,27 +33,25 @@ SPDX-License-Identifier: MIT
#ifndef _GIF_HASH_H_
#define _GIF_HASH_H_
-/** Begin JDK modifications to support building on Windows **/
#ifndef _WIN32
#include
-#endif
-/** End JDK modifications to support building on Windows **/
+#endif /* _WIN32 */
#include
-#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
-#define HT_KEY_MASK 0x1FFF /* 13bits keys */
-#define HT_KEY_NUM_BITS 13 /* 13bits keys */
-#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
-#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
+#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
+#define HT_KEY_MASK 0x1FFF /* 13bits keys */
+#define HT_KEY_NUM_BITS 13 /* 13bits keys */
+#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
+#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
/* The 32 bits of the long are divided into two parts for the key & code: */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
-/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
+/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
/* The key is the upper 20 bits. The code is the lower 12. */
-#define HT_GET_KEY(l) (l >> 12)
-#define HT_GET_CODE(l) (l & 0x0FFF)
-#define HT_PUT_KEY(l) (l << 12)
-#define HT_PUT_CODE(l) (l & 0x0FFF)
+#define HT_GET_KEY(l) (l >> 12)
+#define HT_GET_CODE(l) (l & 0x0FFF)
+#define HT_PUT_KEY(l) (l << 12)
+#define HT_PUT_CODE(l) (l & 0x0FFF)
typedef struct GifHashTableType {
uint32_t HTable[HT_SIZE];
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h b/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
index f739b36adfd..74a2e969c0d 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
@@ -39,27 +39,19 @@ extern "C" {
#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 2
-#define GIFLIB_RELEASE 1
+#define GIFLIB_RELEASE 2
-#define GIF_ERROR 0
-#define GIF_OK 1
+#define GIF_ERROR 0
+#define GIF_OK 1
+#include
#include
-/** Begin JDK modifications to support building using old compilers**/
-//#include
-#ifdef bool
-#undef bool
-#endif
-typedef int bool;
-#define false 0
-#define true 1
-/** End JDK modifications to support building using old compilers**/
-
-#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
+
+#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
-#define GIF_VERSION_POS 3 /* Version first character in stamp. */
-#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
-#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
+#define GIF_VERSION_POS 3 /* Version first character in stamp. */
+#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
+#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
@@ -75,24 +67,24 @@ typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
bool SortFlag;
- GifColorType *Colors; /* on malloc(3) heap */
+ GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
- GifWord Left, Top, Width, Height; /* Current image dimensions. */
- bool Interlace; /* Sequential/Interlaced lines. */
- ColorMapObject *ColorMap; /* The local color map */
+ GifWord Left, Top, Width, Height; /* Current image dimensions. */
+ bool Interlace; /* Sequential/Interlaced lines. */
+ ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct ExtensionBlock {
int ByteCount;
- GifByteType *Bytes; /* on malloc(3) heap */
- int Function; /* The block function code */
-#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
-#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
-#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
-#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
-#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
+ GifByteType *Bytes; /* on malloc(3) heap */
+ int Function; /* The block function code */
+#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
+#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
+#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
+#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
+#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
} ExtensionBlock;
typedef struct SavedImage {
@@ -103,22 +95,22 @@ typedef struct SavedImage {
} SavedImage;
typedef struct GifFileType {
- GifWord SWidth, SHeight; /* Size of virtual canvas */
- GifWord SColorResolution; /* How many colors can we generate? */
- GifWord SBackGroundColor; /* Background color for virtual canvas */
- GifByteType AspectByte; /* Used to compute pixel aspect ratio */
- ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
- int ImageCount; /* Number of current image (both APIs) */
- GifImageDesc Image; /* Current image (low-level API) */
- SavedImage *SavedImages; /* Image sequence (high-level API) */
- int ExtensionBlockCount; /* Count extensions past last image */
+ GifWord SWidth, SHeight; /* Size of virtual canvas */
+ GifWord SColorResolution; /* How many colors can we generate? */
+ GifWord SBackGroundColor; /* Background color for virtual canvas */
+ GifByteType AspectByte; /* Used to compute pixel aspect ratio */
+ ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
+ int ImageCount; /* Number of current image (both APIs) */
+ GifImageDesc Image; /* Current image (low-level API) */
+ SavedImage *SavedImages; /* Image sequence (high-level API) */
+ int ExtensionBlockCount; /* Count extensions past last image */
ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
int Error; /* Last error condition reported */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
-#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
+#define GIF_ASPECT_RATIO(n) ((n) + 15.0 / 64.0)
typedef enum {
UNDEFINED_RECORD_TYPE,
@@ -129,12 +121,12 @@ typedef enum {
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
-typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
+typedef int (*InputFunc)(GifFileType *, GifByteType *, int);
/* func type to write gif data to arbitrary targets.
* Returns count of bytes written. (MRB)
*/
-typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
+typedef int (*OutputFunc)(GifFileType *, const GifByteType *, int);
/******************************************************************************
GIF89 structures
@@ -142,14 +134,14 @@ typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
typedef struct GraphicsControlBlock {
int DisposalMode;
-#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
-#define DISPOSE_DO_NOT 1 /* Leave image in place */
-#define DISPOSE_BACKGROUND 2 /* Set area too background color */
-#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
- bool UserInputFlag; /* User confirmation required before disposal */
- int DelayTime; /* pre-display delay in 0.01sec units */
- int TransparentColor; /* Palette index for transparency, -1 if none */
-#define NO_TRANSPARENT_COLOR -1
+#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
+#define DISPOSE_DO_NOT 1 /* Leave image in place */
+#define DISPOSE_BACKGROUND 2 /* Set area too background color */
+#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
+ bool UserInputFlag; /* User confirmation required before disposal */
+ int DelayTime; /* pre-display delay in 0.01sec units */
+ int TransparentColor; /* Palette index for transparency, -1 if none */
+#define NO_TRANSPARENT_COLOR -1
} GraphicsControlBlock;
/******************************************************************************
@@ -161,49 +153,44 @@ GifFileType *EGifOpenFileName(const char *GifFileName,
const bool GifTestExistence, int *Error);
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
-int EGifSpew(GifFileType * GifFile);
+int EGifSpew(GifFileType *GifFile);
const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
-#define E_GIF_SUCCEEDED 0
-#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
-#define E_GIF_ERR_WRITE_FAILED 2
-#define E_GIF_ERR_HAS_SCRN_DSCR 3
-#define E_GIF_ERR_HAS_IMAG_DSCR 4
-#define E_GIF_ERR_NO_COLOR_MAP 5
-#define E_GIF_ERR_DATA_TOO_BIG 6
+#define E_GIF_SUCCEEDED 0
+#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
+#define E_GIF_ERR_WRITE_FAILED 2
+#define E_GIF_ERR_HAS_SCRN_DSCR 3
+#define E_GIF_ERR_HAS_IMAG_DSCR 4
+#define E_GIF_ERR_NO_COLOR_MAP 5
+#define E_GIF_ERR_DATA_TOO_BIG 6
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
-#define E_GIF_ERR_DISK_IS_FULL 8
-#define E_GIF_ERR_CLOSE_FAILED 9
-#define E_GIF_ERR_NOT_WRITEABLE 10
+#define E_GIF_ERR_DISK_IS_FULL 8
+#define E_GIF_ERR_CLOSE_FAILED 9
+#define E_GIF_ERR_NOT_WRITEABLE 10
/* These are legacy. You probably do not want to call them directly */
-int EGifPutScreenDesc(GifFileType *GifFile,
- const int GifWidth, const int GifHeight,
- const int GifColorRes,
+int EGifPutScreenDesc(GifFileType *GifFile, const int GifWidth,
+ const int GifHeight, const int GifColorRes,
const int GifBackGround,
const ColorMapObject *GifColorMap);
-int EGifPutImageDesc(GifFileType *GifFile,
- const int GifLeft, const int GifTop,
+int EGifPutImageDesc(GifFileType *GifFile, const int GifLeft, const int GifTop,
const int GifWidth, const int GifHeight,
const bool GifInterlace,
const ColorMapObject *GifColorMap);
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
-int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
- int GifLineLen);
+int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, const char *GifComment);
int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
-int EGifPutExtensionBlock(GifFileType *GifFile,
- const int GifExtLen, const void *GifExtension);
+int EGifPutExtensionBlock(GifFileType *GifFile, const int GifExtLen,
+ const void *GifExtension);
int EGifPutExtensionTrailer(GifFileType *GifFile);
int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
- const int GifExtLen,
- const void *GifExtension);
+ const int GifExtLen, const void *GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
const GifByteType *GifCodeBlock);
-int EGifPutCodeNext(GifFileType *GifFile,
- const GifByteType *GifCodeBlock);
+int EGifPutCodeNext(GifFileType *GifFile, const GifByteType *GifCodeBlock);
/******************************************************************************
GIF decoding routines
@@ -212,24 +199,25 @@ int EGifPutCodeNext(GifFileType *GifFile,
/* Main entry points */
GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
-int DGifSlurp(GifFileType * GifFile);
-GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
- int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
-
-#define D_GIF_SUCCEEDED 0
-#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
-#define D_GIF_ERR_READ_FAILED 102
-#define D_GIF_ERR_NOT_GIF_FILE 103
-#define D_GIF_ERR_NO_SCRN_DSCR 104
-#define D_GIF_ERR_NO_IMAG_DSCR 105
-#define D_GIF_ERR_NO_COLOR_MAP 106
-#define D_GIF_ERR_WRONG_RECORD 107
-#define D_GIF_ERR_DATA_TOO_BIG 108
+int DGifSlurp(GifFileType *GifFile);
+GifFileType *DGifOpen(void *userPtr, InputFunc readFunc,
+ int *Error); /* new one (TVT) */
+int DGifCloseFile(GifFileType *GifFile, int *ErrorCode);
+
+#define D_GIF_SUCCEEDED 0
+#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
+#define D_GIF_ERR_READ_FAILED 102
+#define D_GIF_ERR_NOT_GIF_FILE 103
+#define D_GIF_ERR_NO_SCRN_DSCR 104
+#define D_GIF_ERR_NO_IMAG_DSCR 105
+#define D_GIF_ERR_NO_COLOR_MAP 106
+#define D_GIF_ERR_WRONG_RECORD 107
+#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
-#define D_GIF_ERR_CLOSE_FAILED 110
-#define D_GIF_ERR_NOT_READABLE 111
-#define D_GIF_ERR_IMAGE_DEFECT 112
-#define D_GIF_ERR_EOF_TOO_SOON 113
+#define D_GIF_ERR_CLOSE_FAILED 110
+#define D_GIF_ERR_NOT_READABLE 111
+#define D_GIF_ERR_IMAGE_DEFECT 112
+#define D_GIF_ERR_EOF_TOO_SOON 113
/* These are legacy. You probably do not want to call them directly */
int DGifGetScreenDesc(GifFileType *GifFile);
@@ -247,11 +235,10 @@ int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
const char *DGifGetGifVersion(GifFileType *GifFile);
-
/******************************************************************************
Error handling and reporting.
******************************************************************************/
-extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
+extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
/*****************************************************************************
Everything below this point is new after version 1.2, supporting `slurp
@@ -263,26 +250,26 @@ extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
******************************************************************************/
extern ColorMapObject *GifMakeMapObject(int ColorCount,
- const GifColorType *ColorMap);
+ const GifColorType *ColorMap);
extern void GifFreeMapObject(ColorMapObject *Object);
extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
- const ColorMapObject *ColorIn2,
- GifPixelType ColorTransIn2[]);
+ const ColorMapObject *ColorIn2,
+ GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);
/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
-extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
+extern void GifApplyTranslation(SavedImage *Image,
+ const GifPixelType Translation[]);
extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
- ExtensionBlock **ExtensionBlocks,
- int Function,
+ ExtensionBlock **ExtensionBlocks, int Function,
unsigned int Len, unsigned char ExtData[]);
extern void GifFreeExtensions(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks);
extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
- const SavedImage *CopyFrom);
+ const SavedImage *CopyFrom);
extern void GifFreeSavedImages(GifFileType *GifFile);
/******************************************************************************
@@ -295,37 +282,31 @@ int DGifExtensionToGCB(const size_t GifExtensionLength,
size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
GifByteType *GifExtension);
-int DGifSavedExtensionToGCB(GifFileType *GifFile,
- int ImageIndex,
+int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex,
GraphicsControlBlock *GCB);
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
- GifFileType *GifFile,
- int ImageIndex);
+ GifFileType *GifFile, int ImageIndex);
/******************************************************************************
The library's internal utility font
******************************************************************************/
-#define GIF_FONT_WIDTH 8
+#define GIF_FONT_WIDTH 8
#define GIF_FONT_HEIGHT 8
extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
-extern void GifDrawText8x8(SavedImage *Image,
- const int x, const int y,
- const char *legend, const int color);
+extern void GifDrawText8x8(SavedImage *Image, const int x, const int y,
+ const char *legend, const int color);
-extern void GifDrawBox(SavedImage *Image,
- const int x, const int y,
- const int w, const int d, const int color);
+extern void GifDrawBox(SavedImage *Image, const int x, const int y, const int w,
+ const int d, const int color);
-extern void GifDrawRectangle(SavedImage *Image,
- const int x, const int y,
- const int w, const int d, const int color);
+extern void GifDrawRectangle(SavedImage *Image, const int x, const int y,
+ const int w, const int d, const int color);
-extern void GifDrawBoxedText8x8(SavedImage *Image,
- const int x, const int y,
- const char *legend,
- const int border, const int bg, const int fg);
+extern void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y,
+ const char *legend, const int border,
+ const int bg, const int fg);
#ifdef __cplusplus
}
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h b/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h
index 4f832676ffc..f905e0d7b48 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h
@@ -33,52 +33,54 @@ SPDX-License-Identifier: MIT
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
-#include "gif_lib.h"
#include "gif_hash.h"
+#include "gif_lib.h"
#ifndef SIZE_MAX
- #define SIZE_MAX UINTPTR_MAX
+#define SIZE_MAX UINTPTR_MAX
#endif
-#define EXTENSION_INTRODUCER 0x21
-#define DESCRIPTOR_INTRODUCER 0x2c
-#define TERMINATOR_INTRODUCER 0x3b
+#define EXTENSION_INTRODUCER 0x21
+#define DESCRIPTOR_INTRODUCER 0x2c
+#define TERMINATOR_INTRODUCER 0x3b
-#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
-#define LZ_BITS 12
+#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
+#define LZ_BITS 12
-#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
-#define FIRST_CODE 4097 /* Impossible code, to signal first. */
-#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
+#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
+#define FIRST_CODE 4097 /* Impossible code, to signal first. */
+#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
-#define FILE_STATE_WRITE 0x01
-#define FILE_STATE_SCREEN 0x02
-#define FILE_STATE_IMAGE 0x04
-#define FILE_STATE_READ 0x08
+#define FILE_STATE_WRITE 0x01
+#define FILE_STATE_SCREEN 0x02
+#define FILE_STATE_IMAGE 0x04
+#define FILE_STATE_READ 0x08
-#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
-#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
+#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
+#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
typedef struct GifFilePrivateType {
- GifWord FileState, FileHandle, /* Where all this data goes to! */
- BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
- ClearCode, /* The CLEAR LZ code. */
- EOFCode, /* The EOF LZ code. */
- RunningCode, /* The next code algorithm can generate. */
- RunningBits, /* The number of bits required to represent RunningCode. */
- MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
- LastCode, /* The code before the current code. */
- CrntCode, /* Current algorithm code. */
- StackPtr, /* For character stack (see below). */
- CrntShiftState; /* Number of bits in CrntShiftDWord. */
- unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
- unsigned long PixelCount; /* Number of pixels in image. */
- FILE *File; /* File as stream. */
- InputFunc Read; /* function to read gif input (TVT) */
- OutputFunc Write; /* function to write gif output (MRB) */
- GifByteType Buf[256]; /* Compressed input is buffered here. */
+ GifWord FileState, FileHandle, /* Where all this data goes to! */
+ BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
+ ClearCode, /* The CLEAR LZ code. */
+ EOFCode, /* The EOF LZ code. */
+ RunningCode, /* The next code algorithm can generate. */
+ RunningBits, /* The number of bits required to represent
+ RunningCode. */
+ MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits.
+ */
+ LastCode, /* The code before the current code. */
+ CrntCode, /* Current algorithm code. */
+ StackPtr, /* For character stack (see below). */
+ CrntShiftState; /* Number of bits in CrntShiftDWord. */
+ unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
+ unsigned long PixelCount; /* Number of pixels in image. */
+ FILE *File; /* File as stream. */
+ InputFunc Read; /* function to read gif input (TVT) */
+ OutputFunc Write; /* function to write gif output (MRB) */
+ GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
- GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
+ GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
GifHashTableType *HashTable;
bool gif89;
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c b/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c
index 75b74b4fba0..5aef3044558 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c
@@ -30,59 +30,59 @@ SPDX-License-Identifier: MIT
****************************************************************************/
-#include
#include
+#include
#include
#include "gif_lib.h"
#include "gif_lib_private.h"
-#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/******************************************************************************
Miscellaneous utility functions
******************************************************************************/
/* return smallest bitfield size n will fit in */
-int
-GifBitSize(int n)
-{
+int GifBitSize(int n) {
register int i;
- for (i = 1; i <= 8; i++)
- if ((1 << i) >= n)
+ for (i = 1; i <= 8; i++) {
+ if ((1 << i) >= n) {
break;
+ }
+ }
return (i);
}
/******************************************************************************
- Color map object functions
+ Color map object functions
******************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
-ColorMapObject *
-GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
-{
+ColorMapObject *GifMakeMapObject(int ColorCount, const GifColorType *ColorMap) {
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
- * make the user know that or should we automatically round up instead? */
+ * make the user know that or should we automatically round up instead?
+ */
if (ColorCount != (1 << GifBitSize(ColorCount))) {
- return ((ColorMapObject *) NULL);
+ return ((ColorMapObject *)NULL);
}
Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
- if (Object == (ColorMapObject *) NULL) {
- return ((ColorMapObject *) NULL);
+ if (Object == (ColorMapObject *)NULL) {
+ return ((ColorMapObject *)NULL);
}
- Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
- if (Object->Colors == (GifColorType *) NULL) {
+ Object->Colors =
+ (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
+ if (Object->Colors == (GifColorType *)NULL) {
free(Object);
- return ((ColorMapObject *) NULL);
+ return ((ColorMapObject *)NULL);
}
Object->ColorCount = ColorCount;
@@ -90,19 +90,17 @@ GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
Object->SortFlag = false;
if (ColorMap != NULL) {
- memcpy((char *)Object->Colors,
- (char *)ColorMap, ColorCount * sizeof(GifColorType));
+ memcpy((char *)Object->Colors, (char *)ColorMap,
+ ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*******************************************************************************
-Free a color map object
+ Free a color map object
*******************************************************************************/
-void
-GifFreeMapObject(ColorMapObject *Object)
-{
+void GifFreeMapObject(ColorMapObject *Object) {
if (Object != NULL) {
(void)free(Object->Colors);
(void)free(Object);
@@ -110,17 +108,14 @@ GifFreeMapObject(ColorMapObject *Object)
}
#ifdef DEBUG
-void
-DumpColorMap(ColorMapObject *Object,
- FILE * fp)
-{
+void DumpColorMap(ColorMapObject *Object, FILE *fp) {
if (Object != NULL) {
int i, j, Len = Object->ColorCount;
for (i = 0; i < Len; i += 4) {
for (j = 0; j < 4 && j < Len; j++) {
- (void)fprintf(fp, "%3d: %02x %02x %02x ", i + j,
- Object->Colors[i + j].Red,
+ (void)fprintf(fp, "%3d: %02x %02x %02x ",
+ i + j, Object->Colors[i + j].Red,
Object->Colors[i + j].Green,
Object->Colors[i + j].Blue);
}
@@ -137,11 +132,9 @@ DumpColorMap(ColorMapObject *Object,
copied iff they didn't exist before. ColorTransIn2 maps the old
ColorIn2 into the ColorUnion color map table./
*******************************************************************************/
-ColorMapObject *
-GifUnionColorMap(const ColorMapObject *ColorIn1,
- const ColorMapObject *ColorIn2,
- GifPixelType ColorTransIn2[])
-{
+ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
+ const ColorMapObject *ColorIn2,
+ GifPixelType ColorTransIn2[]) {
int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
ColorMapObject *ColorUnion;
@@ -152,17 +145,19 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
*/
/* Allocate table which will hold the result for sure. */
- ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
- ColorIn2->ColorCount) * 2, NULL);
+ ColorUnion = GifMakeMapObject(
+ MAX(ColorIn1->ColorCount, ColorIn2->ColorCount) * 2, NULL);
- if (ColorUnion == NULL)
+ if (ColorUnion == NULL) {
return (NULL);
+ }
/*
* Copy ColorIn1 to ColorUnion.
*/
- for (i = 0; i < ColorIn1->ColorCount; i++)
+ for (i = 0; i < ColorIn1->ColorCount; i++) {
ColorUnion->Colors[i] = ColorIn1->Colors[i];
+ }
CrntSlot = ColorIn1->ColorCount;
/*
@@ -172,22 +167,25 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
* of table 1. This is very useful if your display is limited to
* 16 colors.
*/
- while (ColorIn1->Colors[CrntSlot - 1].Red == 0
- && ColorIn1->Colors[CrntSlot - 1].Green == 0
- && ColorIn1->Colors[CrntSlot - 1].Blue == 0)
+ while (ColorIn1->Colors[CrntSlot - 1].Red == 0 &&
+ ColorIn1->Colors[CrntSlot - 1].Green == 0 &&
+ ColorIn1->Colors[CrntSlot - 1].Blue == 0) {
CrntSlot--;
+ }
/* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
/* Let's see if this color already exists: */
- for (j = 0; j < ColorIn1->ColorCount; j++)
- if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
- sizeof(GifColorType)) == 0)
+ for (j = 0; j < ColorIn1->ColorCount; j++) {
+ if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i],
+ sizeof(GifColorType)) == 0) {
break;
+ }
+ }
- if (j < ColorIn1->ColorCount)
- ColorTransIn2[i] = j; /* color exists in Color1 */
- else {
+ if (j < ColorIn1->ColorCount) {
+ ColorTransIn2[i] = j; /* color exists in Color1 */
+ } else {
/* Color is new - copy it to a new slot: */
ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
ColorTransIn2[i] = CrntSlot++;
@@ -196,7 +194,7 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
if (CrntSlot > 256) {
GifFreeMapObject(ColorUnion);
- return ((ColorMapObject *) NULL);
+ return ((ColorMapObject *)NULL);
}
NewGifBitSize = GifBitSize(CrntSlot);
@@ -210,16 +208,17 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
* We know these slots exist because of the way ColorUnion's
* start dimension was computed.
*/
- for (j = CrntSlot; j < RoundUpTo; j++)
+ for (j = CrntSlot; j < RoundUpTo; j++) {
Map[j].Red = Map[j].Green = Map[j].Blue = 0;
+ }
/* perhaps we can shrink the map? */
if (RoundUpTo < ColorUnion->ColorCount) {
- GifColorType *new_map = (GifColorType *)reallocarray(Map,
- RoundUpTo, sizeof(GifColorType));
- if( new_map == NULL ) {
+ GifColorType *new_map = (GifColorType *)reallocarray(
+ Map, RoundUpTo, sizeof(GifColorType));
+ if (new_map == NULL) {
GifFreeMapObject(ColorUnion);
- return ((ColorMapObject *) NULL);
+ return ((ColorMapObject *)NULL);
}
ColorUnion->Colors = new_map;
}
@@ -234,49 +233,49 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
/*******************************************************************************
Apply a given color translation to the raster bits of an image
*******************************************************************************/
-void
-GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
-{
+void GifApplyTranslation(SavedImage *Image, const GifPixelType Translation[]) {
register int i;
- register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
+ register int RasterSize =
+ Image->ImageDesc.Height * Image->ImageDesc.Width;
- for (i = 0; i < RasterSize; i++)
+ for (i = 0; i < RasterSize; i++) {
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
+ }
}
/******************************************************************************
Extension record functions
******************************************************************************/
-int
-GifAddExtensionBlock(int *ExtensionBlockCount,
- ExtensionBlock **ExtensionBlocks,
- int Function,
- unsigned int Len,
- unsigned char ExtData[])
-{
+int GifAddExtensionBlock(int *ExtensionBlockCount,
+ ExtensionBlock **ExtensionBlocks, int Function,
+ unsigned int Len, unsigned char ExtData[]) {
ExtensionBlock *ep;
- if (*ExtensionBlocks == NULL)
- *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
- else {
- ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
- (*ExtensionBlocks, (*ExtensionBlockCount + 1),
- sizeof(ExtensionBlock));
- if( ep_new == NULL )
+ if (*ExtensionBlocks == NULL) {
+ *ExtensionBlocks =
+ (ExtensionBlock *)malloc(sizeof(ExtensionBlock));
+ } else {
+ ExtensionBlock *ep_new = (ExtensionBlock *)reallocarray(
+ *ExtensionBlocks, (*ExtensionBlockCount + 1),
+ sizeof(ExtensionBlock));
+ if (ep_new == NULL) {
return (GIF_ERROR);
+ }
*ExtensionBlocks = ep_new;
}
- if (*ExtensionBlocks == NULL)
+ if (*ExtensionBlocks == NULL) {
return (GIF_ERROR);
+ }
ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
ep->Function = Function;
- ep->ByteCount=Len;
+ ep->ByteCount = Len;
ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
- if (ep->Bytes == NULL)
+ if (ep->Bytes == NULL) {
return (GIF_ERROR);
+ }
if (ExtData != NULL) {
memcpy(ep->Bytes, ExtData, Len);
@@ -285,38 +284,36 @@ GifAddExtensionBlock(int *ExtensionBlockCount,
return (GIF_OK);
}
-void
-GifFreeExtensions(int *ExtensionBlockCount,
- ExtensionBlock **ExtensionBlocks)
-{
+void GifFreeExtensions(int *ExtensionBlockCount,
+ ExtensionBlock **ExtensionBlocks) {
ExtensionBlock *ep;
- if (*ExtensionBlocks == NULL)
+ if (*ExtensionBlocks == NULL) {
return;
+ }
for (ep = *ExtensionBlocks;
- ep < (*ExtensionBlocks + *ExtensionBlockCount);
- ep++)
+ ep < (*ExtensionBlocks + *ExtensionBlockCount); ep++) {
(void)free((char *)ep->Bytes);
+ }
(void)free((char *)*ExtensionBlocks);
*ExtensionBlocks = NULL;
*ExtensionBlockCount = 0;
}
/******************************************************************************
- Image block allocation functions
+ Image block allocation functions
******************************************************************************/
/* Private Function:
* Frees the last image in the GifFile->SavedImages array
*/
-void
-FreeLastSavedImage(GifFileType *GifFile)
-{
+void FreeLastSavedImage(GifFileType *GifFile) {
SavedImage *sp;
- if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
+ if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
return;
+ }
/* Remove one SavedImage from the GifFile */
GifFile->ImageCount--;
@@ -329,54 +326,58 @@ FreeLastSavedImage(GifFileType *GifFile)
}
/* Deallocate the image data */
- if (sp->RasterBits != NULL)
+ if (sp->RasterBits != NULL) {
free((char *)sp->RasterBits);
+ }
/* Deallocate any extensions */
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
/*** FIXME: We could realloc the GifFile->SavedImages structure but is
* there a point to it? Saves some memory but we'd have to do it every
- * time. If this is used in GifFreeSavedImages then it would be inefficient
- * (The whole array is going to be deallocated.) If we just use it when
- * we want to free the last Image it's convenient to do it here.
+ * time. If this is used in GifFreeSavedImages then it would be
+ * inefficient (The whole array is going to be deallocated.) If we just
+ * use it when we want to free the last Image it's convenient to do it
+ * here.
*/
}
/*
* Append an image block to the SavedImages array
*/
-SavedImage *
-GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
-{
- if (GifFile->SavedImages == NULL)
+SavedImage *GifMakeSavedImage(GifFileType *GifFile,
+ const SavedImage *CopyFrom) {
+ // cppcheck-suppress ctunullpointer
+ if (GifFile->SavedImages == NULL) {
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
- else {
- SavedImage* newSavedImages = (SavedImage *)reallocarray(GifFile->SavedImages,
- (GifFile->ImageCount + 1), sizeof(SavedImage));
- if( newSavedImages == NULL)
+ } else {
+ SavedImage *newSavedImages = (SavedImage *)reallocarray(
+ GifFile->SavedImages, (GifFile->ImageCount + 1),
+ sizeof(SavedImage));
+ if (newSavedImages == NULL) {
return ((SavedImage *)NULL);
+ }
GifFile->SavedImages = newSavedImages;
}
- if (GifFile->SavedImages == NULL)
+ if (GifFile->SavedImages == NULL) {
return ((SavedImage *)NULL);
- else {
+ } else {
SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
if (CopyFrom != NULL) {
memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
/*
- * Make our own allocated copies of the heap fields in the
- * copied record. This guards against potential aliasing
- * problems.
+ * Make our own allocated copies of the heap fields in
+ * the copied record. This guards against potential
+ * aliasing problems.
*/
/* first, the local color map */
if (CopyFrom->ImageDesc.ColorMap != NULL) {
sp->ImageDesc.ColorMap = GifMakeMapObject(
- CopyFrom->ImageDesc.ColorMap->ColorCount,
- CopyFrom->ImageDesc.ColorMap->Colors);
+ CopyFrom->ImageDesc.ColorMap->ColorCount,
+ CopyFrom->ImageDesc.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
@@ -384,32 +385,36 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
}
/* next, the raster */
- sp->RasterBits = (unsigned char *)reallocarray(NULL,
- (CopyFrom->ImageDesc.Height *
- CopyFrom->ImageDesc.Width),
- sizeof(GifPixelType));
+ sp->RasterBits = (unsigned char *)reallocarray(
+ NULL,
+ (CopyFrom->ImageDesc.Height *
+ CopyFrom->ImageDesc.Width),
+ sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->RasterBits, CopyFrom->RasterBits,
- sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
- CopyFrom->ImageDesc.Width);
+ sizeof(GifPixelType) *
+ CopyFrom->ImageDesc.Height *
+ CopyFrom->ImageDesc.Width);
/* finally, the extension blocks */
if (CopyFrom->ExtensionBlocks != NULL) {
- sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL,
- CopyFrom->ExtensionBlockCount,
- sizeof(ExtensionBlock));
+ sp->ExtensionBlocks =
+ (ExtensionBlock *)reallocarray(
+ NULL, CopyFrom->ExtensionBlockCount,
+ sizeof(ExtensionBlock));
if (sp->ExtensionBlocks == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
- memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
- sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
+ memcpy(sp->ExtensionBlocks,
+ CopyFrom->ExtensionBlocks,
+ sizeof(ExtensionBlock) *
+ CopyFrom->ExtensionBlockCount);
}
- }
- else {
+ } else {
memset((char *)sp, '\0', sizeof(SavedImage));
}
@@ -417,9 +422,7 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
}
}
-void
-GifFreeSavedImages(GifFileType *GifFile)
-{
+void GifFreeSavedImages(GifFileType *GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
@@ -432,10 +435,12 @@ GifFreeSavedImages(GifFileType *GifFile)
sp->ImageDesc.ColorMap = NULL;
}
- if (sp->RasterBits != NULL)
+ if (sp->RasterBits != NULL) {
free((char *)sp->RasterBits);
+ }
- GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
+ GifFreeExtensions(&sp->ExtensionBlockCount,
+ &sp->ExtensionBlocks);
}
free((char *)GifFile->SavedImages);
GifFile->SavedImages = NULL;
diff --git a/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c b/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c
index 452df69d7cd..7420af674c5 100644
--- a/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c
+++ b/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c
@@ -28,24 +28,22 @@
* SPDX-License-Identifier: MIT
*/
-#include
#include
#include
#include
+#include
#ifndef SIZE_MAX
- #define SIZE_MAX UINTPTR_MAX
+#define SIZE_MAX UINTPTR_MAX
#endif
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
-#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
-void *
-openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
-{
+void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size) {
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
errno = ENOMEM;
@@ -93,7 +91,8 @@ openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
* fuzzing on one platform may not detect zero-size allocation
* problems on other platforms.
*/
- if (size == 0 || nmemb == 0)
+ if (size == 0 || nmemb == 0) {
return NULL;
+ }
return realloc(optr, size * nmemb);
}
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
index 2d8c585c0e7..441b57ecf1a 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
@@ -6129,6 +6129,73 @@ Version 1.6.40 [June 21, 2023]
Updated the configurations and the scripts for continuous integration.
Cleaned up the code, the build scripts, and the documentation.
+Version 1.6.41 [January 24, 2024]
+ Added SIMD-optimized code for the LoongArch LSX hardware.
+ (Contributed by GuXiWei, JinBo and ZhangLixia)
+ Fixed the run-time discovery of MIPS MSA hardware.
+ (Contributed by Sui Jingfeng)
+ Fixed an off-by-one error in the function png_do_check_palette_indexes(),
+ which failed to recognize errors that might have existed in the first
+ column of a broken palette-encoded image. This was a benign regression
+ accidentally introduced in libpng-1.6.33. No pixel was harmed.
+ (Contributed by Adam Richter; reviewed by John Bowler)
+ Fixed, improved and modernized the contrib/pngminus programs, i.e.,
+ png2pnm.c and pnm2png.c
+ Removed old and peculiar portability hacks that were meant to silence
+ warnings issued by gcc version 7.1 alone.
+ (Contributed by John Bowler)
+ Fixed and modernized the CMake file, and raised the minimum required
+ CMake version from 3.1 to 3.6.
+ (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.)
+ Allowed the configure script to disable the building of auxiliary tools
+ and tests, thus catching up with the CMake file.
+ (Contributed by Carlo Bramini)
+ Fixed a build issue on Mac.
+ (Contributed by Zixu Wang)
+ Moved the Autoconf macro files to scripts/autoconf.
+ Moved the CMake files (except for the main CMakeLists.txt) to
+ scripts/cmake and moved the list of their contributing authors to
+ scripts/cmake/AUTHORS.md
+ Updated the CI configurations and scripts.
+ Relicensed the CI scripts to the MIT License.
+ Improved the test coverage.
+ (Contributed by John Bowler)
+
+Version 1.6.42 [January 29, 2024]
+ Fixed the implementation of the macro function png_check_sig().
+ This was an API regression, introduced in libpng-1.6.41.
+ (Reported by Matthieu Darbois)
+ Fixed and updated the libpng manual.
+
+Version 1.6.43 [February 23, 2024]
+ Fixed the row width check in png_check_IHDR().
+ This corrected a bug that was specific to the 16-bit platforms,
+ and removed a spurious compiler warning from the 64-bit builds.
+ (Reported by Jacek Caban; fixed by John Bowler)
+ Added eXIf chunk support to the push-mode reader in pngpread.c.
+ (Contributed by Chris Blume)
+ Added contrib/pngexif for the benefit of the users who would like
+ to inspect the content of eXIf chunks.
+ Added contrib/conftest/basic.dfa, a basic build-time configuration.
+ (Contributed by John Bowler)
+ Fixed a preprocessor condition in pngread.c that broke build-time
+ configurations like contrib/conftest/pngcp.dfa.
+ (Contributed by John Bowler)
+ Added CMake build support for LoongArch LSX.
+ (Contributed by GuXiWei)
+ Fixed a CMake build error that occurred under a peculiar state of the
+ dependency tree. This was a regression introduced in libpng-1.6.41.
+ (Contributed by Dan Rosser)
+ Marked the installed libpng headers as system headers in CMake.
+ (Contributed by Benjamin Buch)
+ Updated the build support for RISCOS.
+ (Contributed by Cameron Cawley)
+ Updated the makefiles to allow cross-platform builds to initialize
+ conventional make variables like AR and ARFLAGS.
+ Added various improvements to the CI scripts in areas like version
+ consistency verification and text linting.
+ Added version consistency verification to pngtest.c also.
+
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
index 086d1c2fda6..25f298f0fcf 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
@@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
PNG Reference Library License version 2
---------------------------------------
- * Copyright (c) 1995-2023 The PNG Reference Library Authors.
- * Copyright (c) 2018-2023 Cosmin Truta.
+ * Copyright (c) 1995-2024 The PNG Reference Library Authors.
+ * Copyright (c) 2018-2024 Cosmin Truta.
* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* Copyright (c) 1996-1997 Andreas Dilger.
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/README b/src/java.desktop/share/native/libsplashscreen/libpng/README
index dedd2c1639e..a6ca3ae9f94 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/README
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.40
+README for libpng version 1.6.43
================================
See the note about version numbers near the top of `png.h`.
@@ -142,10 +142,11 @@ Files included in this distribution
pngwrite.c => High-level write functions
pngwtran.c => Write data transformations
pngwutil.c => Write utility functions
- arm/ => Optimized code for the ARM platform
- intel/ => Optimized code for the INTEL-SSE2 platform
- mips/ => Optimized code for the MIPS platform
- powerpc/ => Optimized code for the PowerPC platform
+ arm/ => Optimized code for ARM Neon
+ intel/ => Optimized code for INTEL SSE2
+ loongarch/ => Optimized code for LoongArch LSX
+ mips/ => Optimized code for MIPS MSA and MIPS MMI
+ powerpc/ => Optimized code for PowerPC VSX
ci/ => Scripts for continuous integration
contrib/ => External contributions
arm-neon/ => Optimized code for the ARM-NEON platform
@@ -158,6 +159,7 @@ Files included in this distribution
libtests/ => Test programs
oss-fuzz/ => Files used by the OSS-Fuzz project for fuzz-testing
libpng
+ pngexif/ => Program to inspect the EXIF information in PNG files
pngminim/ => Minimal decoder, encoder, and progressive decoder
programs demonstrating the use of pngusr.dfa
pngminus/ => Simple pnm2png and png2pnm programs
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt b/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt
index 93c8f5bb703..88200db5d73 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt
@@ -37,18 +37,21 @@ and instead just tweak the existing one.
First cd into the libpng folder and run the following script.
+ shopt -s nullglob
for f in *.c *.h;
- do
- # replace tabs with spaces
- expand ${f} > ${f}.tmp;
- mv ${f}.tmp $f;
-
- # fix line endings to LF
- sed -i -e 's/\r$//g' ${f};
-
- # remove trailing spaces
- sed -i -e 's/[ ]* $//g' ${f};
- done
+ do
+ # replace tabs with spaces
+ expand ${f} > ${f}.tmp
+ mv ${f}.tmp $f
+
+ # fix line endings to LF
+ sed -e 's/\r$//g' ${f} > ${f}.tmp
+ mv ${f}.tmp $f
+
+ # remove trailing spaces
+ sed -e 's/[ ]* $//g' ${f} > ${f}.tmp
+ mv ${f}.tmp $f
+ done
6) As with all native code, run it through the official build systems, in case
the updated code trigger any fatal warnings with the official compilers.
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.c b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
index 91a92e5f718..232dff876c7 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2023 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -42,27 +42,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_40 Your_png_h_is_not_version_1_6_40;
-
-#ifdef __GNUC__
-/* The version tests may need to be added to, but the problem warning has
- * consistently been fixed in GCC versions which obtain wide-spread release.
- * The problem is that many versions of GCC rearrange comparison expressions in
- * the optimizer in such a way that the results of the comparison will change
- * if signed integer overflow occurs. Such comparisons are not permitted in
- * ANSI C90, however GCC isn't clever enough to work out that that do not occur
- * below in png_ascii_from_fp and png_muldiv, so it produces a warning with
- * -Wextra. Unfortunately this is highly dependent on the optimizer and the
- * machine architecture so the warning comes and goes unpredictably and is
- * impossible to "fix", even were that a good idea.
- */
-#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
-#define GCC_STRICT_OVERFLOW 1
-#endif /* GNU 7.1.x */
-#endif /* GNU */
-#ifndef GCC_STRICT_OVERFLOW
-#define GCC_STRICT_OVERFLOW 0
-#endif
+typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@@ -101,21 +81,21 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
int PNGAPI
png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
{
- png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
if (num_to_check > 8)
num_to_check = 8;
else if (num_to_check < 1)
- return (-1);
+ return -1;
if (start > 7)
- return (-1);
+ return -1;
if (start + num_to_check > 8)
num_to_check = 8 - start;
- return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
+ return memcmp(&sig[start], &png_signature[start], num_to_check);
}
#endif /* READ */
@@ -475,7 +455,6 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
memset(info_ptr, 0, (sizeof *info_ptr));
}
-/* The following API is not called internally */
void PNGAPI
png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
int freer, png_uint_32 mask)
@@ -714,9 +693,9 @@ png_voidp PNGAPI
png_get_io_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return (NULL);
+ return NULL;
- return (png_ptr->io_ptr);
+ return png_ptr->io_ptr;
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
@@ -780,7 +759,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
{
size_t pos = 0;
- char number_buf[5]; /* enough for a four-digit year */
+ char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */
# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
# define APPEND_NUMBER(format, value)\
@@ -843,8 +822,8 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
- "libpng version 1.6.40" PNG_STRING_NEWLINE \
- "Copyright (c) 2018-2023 Cosmin Truta" PNG_STRING_NEWLINE \
+ "libpng version 1.6.43" PNG_STRING_NEWLINE \
+ "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
@@ -1005,7 +984,7 @@ png_reset_zstream(png_structrp png_ptr)
return Z_STREAM_ERROR;
/* WARNING: this resets the window bits to the maximum! */
- return (inflateReset(&png_ptr->zstream));
+ return inflateReset(&png_ptr->zstream);
}
#endif /* READ */
@@ -1014,7 +993,7 @@ png_uint_32 PNGAPI
png_access_version_number(void)
{
/* Version of *.c files used when building libpng */
- return((png_uint_32)PNG_LIBPNG_VER);
+ return (png_uint_32)PNG_LIBPNG_VER;
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
@@ -1870,14 +1849,14 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
}
# ifdef PNG_WARNINGS_SUPPORTED
else
- {
- char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
+ {
+ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
- pos = png_safecat(message, (sizeof message), pos,
- png_format_number(number, number+(sizeof number),
- PNG_NUMBER_FORMAT_x, value));
- pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
- }
+ pos = png_safecat(message, (sizeof message), pos,
+ png_format_number(number, number+(sizeof number),
+ PNG_NUMBER_FORMAT_x, value));
+ pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
+ }
# endif
/* The 'reason' is an arbitrary message, allow +79 maximum 195 */
pos = png_safecat(message, (sizeof message), pos, reason);
@@ -2560,17 +2539,6 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
#endif /* COLORSPACE */
-#ifdef __GNUC__
-/* This exists solely to work round a warning from GNU C. */
-static int /* PRIVATE */
-png_gt(size_t a, size_t b)
-{
- return a > b;
-}
-#else
-# define png_gt(a,b) ((a) > (b))
-#endif
-
void /* PRIVATE */
png_check_IHDR(png_const_structrp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
@@ -2592,8 +2560,16 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
- if (png_gt(((width + 7) & (~7U)),
- ((PNG_SIZE_MAX
+ /* The bit mask on the first line below must be at least as big as a
+ * png_uint_32. "~7U" is not adequate on 16-bit systems because it will
+ * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the
+ * type of the result at least as bit (in bits) as the RHS of the > operator
+ * which also avoids a common warning on 64-bit systems that the comparison
+ * of (png_uint_32) against the constant value on the RHS will always be
+ * false.
+ */
+ if (((width + 7) & ~(png_alloc_size_t)7) >
+ (((PNG_SIZE_MAX
- 48 /* big_row_buf hack */
- 1) /* filter byte */
/ 8) /* 8-byte RGBA pixels */
@@ -2919,14 +2895,6 @@ png_pow10(int power)
/* Function to format a floating point value in ASCII with a given
* precision.
*/
-#if GCC_STRICT_OVERFLOW
-#pragma GCC diagnostic push
-/* The problem arises below with exp_b10, which can never overflow because it
- * comes, originally, from frexp and is therefore limited to a range which is
- * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
- */
-#pragma GCC diagnostic warning "-Wstrict-overflow=2"
-#endif /* GCC_STRICT_OVERFLOW */
void /* PRIVATE */
png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
double fp, unsigned int precision)
@@ -3248,10 +3216,6 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
/* Here on buffer too small. */
png_error(png_ptr, "ASCII conversion buffer too small");
}
-#if GCC_STRICT_OVERFLOW
-#pragma GCC diagnostic pop
-#endif /* GCC_STRICT_OVERFLOW */
-
# endif /* FLOATING_POINT */
# ifdef PNG_FIXED_POINT_SUPPORTED
@@ -3279,7 +3243,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
if (num <= 0x80000000) /* else overflowed */
{
unsigned int ndigits = 0, first = 16 /* flag value */;
- char digits[10];
+ char digits[10] = {0};
while (num)
{
@@ -3364,15 +3328,6 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
* the nearest .00001). Overflow and divide by zero are signalled in
* the result, a boolean - true on success, false on overflow.
*/
-#if GCC_STRICT_OVERFLOW /* from above */
-/* It is not obvious which comparison below gets optimized in such a way that
- * signed overflow would change the result; looking through the code does not
- * reveal any tests which have the form GCC complains about, so presumably the
- * optimizer is moving an add or subtract into the 'if' somewhere.
- */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic warning "-Wstrict-overflow=2"
-#endif /* GCC_STRICT_OVERFLOW */
int
png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
png_int_32 divisor)
@@ -3487,9 +3442,6 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
return 0;
}
-#if GCC_STRICT_OVERFLOW
-#pragma GCC diagnostic pop
-#endif /* GCC_STRICT_OVERFLOW */
#endif /* READ_GAMMA || INCH_CONVERSIONS */
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.h b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
index 578841c9580..9f61a773c1d 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
@@ -29,9 +29,9 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * libpng version 1.6.40
+ * libpng version 1.6.43
*
- * Copyright (c) 2018-2023 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -43,7 +43,7 @@
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.35, July 2018:
* Glenn Randers-Pehrson
- * libpng versions 1.6.36, December 2018, through 1.6.40, June 2023:
+ * libpng versions 1.6.36, December 2018, through 1.6.43, February 2024:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@@ -55,8 +55,8 @@
* PNG Reference Library License version 2
* ---------------------------------------
*
- * * Copyright (c) 1995-2023 The PNG Reference Library Authors.
- * * Copyright (c) 2018-2023 Cosmin Truta.
+ * * Copyright (c) 1995-2024 The PNG Reference Library Authors.
+ * * Copyright (c) 2018-2024 Cosmin Truta.
* * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* * Copyright (c) 1996-1997 Andreas Dilger.
* * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -267,7 +267,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
- * 1.6.40 16 10640 16.so.16.40[.0]
+ * 1.6.43 16 10643 16.so.16.43[.0]
*
* Henceforth the source version will match the shared-library major and
* minor numbers; the shared-library major version number will be used for
@@ -283,9 +283,6 @@
* to the info_ptr or png_ptr members through png.h, and the compiled
* application is loaded with a different version of the library.
*
- * DLLNUM will change each time there are forward or backward changes
- * in binary compatibility (e.g., when a new feature is added).
- *
* See libpng.txt or libpng.3 for more information. The PNG specification
* is available as a W3C Recommendation and as an ISO/IEC Standard; see
*
@@ -306,19 +303,21 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.40"
-#define PNG_HEADER_VERSION_STRING " libpng version 1.6.40 - June 21, 2023\n"
+#define PNG_LIBPNG_VER_STRING "1.6.43"
+#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
-#define PNG_LIBPNG_VER_SONUM 16
-#define PNG_LIBPNG_VER_DLLNUM 16
+/* The versions of shared library builds should stay in sync, going forward */
+#define PNG_LIBPNG_VER_SHAREDLIB 16
+#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
+#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 40
+#define PNG_LIBPNG_VER_RELEASE 43
/* This should be zero for a public release, or non-zero for a
- * development version. [Deprecated]
+ * development version.
*/
#define PNG_LIBPNG_VER_BUILD 0
@@ -346,7 +345,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
-#define PNG_LIBPNG_VER 10640 /* 1.6.40 */
+#define PNG_LIBPNG_VER 10643 /* 1.6.43 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -456,7 +455,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_40;
+typedef char* png_libpng_version_1_6_43;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@@ -877,7 +876,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
/* Added to libpng-1.5.4 */
#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */
-#if INT_MAX >= 0x8000 /* else this might break */
+#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */
#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */
#endif
@@ -936,15 +935,15 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
* PNG file. Returns zero if the supplied bytes match the 8-byte PNG
* signature, and non-zero otherwise. Having num_to_check == 0 or
- * start > 7 will always fail (ie return non-zero).
+ * start > 7 will always fail (i.e. return non-zero).
*/
PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
size_t num_to_check));
/* Simple signature checking function. This is the same as calling
- * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0).
*/
-#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
+#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */
/* Allocate and initialize png_ptr struct for reading, and any other memory. */
PNG_EXPORTA(4, png_structp, png_create_read_struct,
@@ -1758,12 +1757,9 @@ PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
png_inforp info_ptr, png_uint_32 free_me, int num));
-/* Reassign responsibility for freeing existing data, whether allocated
+/* Reassign the responsibility for freeing existing data, whether allocated
* by libpng or by the application; this works on the png_info structure passed
- * in, it does not change the state for other png_info structures.
- *
- * It is unlikely that this function works correctly as of 1.6.0 and using it
- * may result either in memory leaks or double free of allocated data.
+ * in, without changing the state for other png_info structures.
*/
PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
png_inforp info_ptr, int freer, png_uint_32 mask));
@@ -3235,11 +3231,18 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
#ifdef PNG_MIPS_MSA_API_SUPPORTED
# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */
#endif
-#define PNG_IGNORE_ADLER32 8
+#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
+# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */
+#endif
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
-# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
+# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions
+ * supported */
#endif
-#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */
+#ifdef PNG_MIPS_MMI_API_SUPPORTED
+# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */
+#endif
+
+#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */
/* Return values: NOTE: there are four values and 'off' is *not* zero */
#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
index 41cbc91d398..b3b441b1122 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
@@ -29,9 +29,9 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * libpng version 1.6.40
+ * libpng version 1.6.43
*
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
index 623735f06f1..ea8dd172197 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -283,7 +283,7 @@ void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
png_alloc_size_t value)
{
- char buffer[PNG_NUMBER_BUFFER_SIZE];
+ char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
}
@@ -293,7 +293,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
{
png_alloc_size_t u;
png_charp str;
- char buffer[PNG_NUMBER_BUFFER_SIZE];
+ char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
/* Avoid overflow by doing the negate in a png_alloc_size_t: */
u = (png_alloc_size_t)value;
@@ -886,7 +886,7 @@ png_get_error_ptr(png_const_structrp png_ptr)
if (png_ptr == NULL)
return NULL;
- return ((png_voidp)png_ptr->error_ptr);
+ return (png_voidp)png_ptr->error_ptr;
}
@@ -961,31 +961,25 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
#endif
int /* PRIVATE */
-png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
+png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg)
{
- volatile png_imagep image = image_in;
- volatile int result;
- volatile png_voidp saved_error_buf;
+ png_voidp saved_error_buf = image->opaque->error_buf;
jmp_buf safe_jmpbuf;
+ int result;
- /* Safely execute function(arg) with png_error returning to this function. */
- saved_error_buf = image->opaque->error_buf;
- result = setjmp(safe_jmpbuf) == 0;
-
- if (result != 0)
+ /* Safely execute function(arg), with png_error returning back here. */
+ if (setjmp(safe_jmpbuf) == 0)
{
-
image->opaque->error_buf = safe_jmpbuf;
result = function(arg);
+ image->opaque->error_buf = saved_error_buf;
+ return result;
}
+ /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */
image->opaque->error_buf = saved_error_buf;
-
- /* And do the cleanup prior to any failure return. */
- if (result == 0)
- png_image_free(image);
-
- return result;
+ png_image_free(image);
+ return 0;
}
#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
#endif /* READ || WRITE */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
index 6e510b27327..41e0a5abc3a 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2023 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -56,22 +56,22 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
* valid tRNS chunk in this case.
*/
if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0)
- return(0);
+ return 0;
#endif
- return(info_ptr->valid & flag);
+ return info_ptr->valid & flag;
}
- return(0);
+ return 0;
}
size_t PNGAPI
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->rowbytes);
+ return info_ptr->rowbytes;
- return(0);
+ return 0;
}
#ifdef PNG_INFO_IMAGE_SUPPORTED
@@ -79,9 +79,9 @@ png_bytepp PNGAPI
png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->row_pointers);
+ return info_ptr->row_pointers;
- return(0);
+ return 0;
}
#endif
@@ -93,7 +93,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->width;
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
@@ -102,7 +102,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->height;
- return (0);
+ return 0;
}
png_byte PNGAPI
@@ -111,7 +111,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->bit_depth;
- return (0);
+ return 0;
}
png_byte PNGAPI
@@ -120,7 +120,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->color_type;
- return (0);
+ return 0;
}
png_byte PNGAPI
@@ -129,7 +129,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->filter_type;
- return (0);
+ return 0;
}
png_byte PNGAPI
@@ -138,7 +138,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->interlace_type;
- return (0);
+ return 0;
}
png_byte PNGAPI
@@ -147,7 +147,7 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->compression_type;
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
@@ -155,21 +155,20 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
+ png_debug(1, "in png_get_x_pixels_per_meter");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
- {
- png_debug1(1, "in %s retrieval function",
- "png_get_x_pixels_per_meter");
-
- if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
- return (info_ptr->x_pixels_per_unit);
- }
+ {
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return info_ptr->x_pixels_per_unit;
+ }
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
@@ -177,42 +176,41 @@ png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
+ png_debug(1, "in png_get_y_pixels_per_meter");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
- png_debug1(1, "in %s retrieval function",
- "png_get_y_pixels_per_meter");
-
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
- return (info_ptr->y_pixels_per_unit);
+ return info_ptr->y_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
+ png_debug(1, "in png_get_pixels_per_meter");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
-
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
- return (info_ptr->x_pixels_per_unit);
+ return info_ptr->x_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
#ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -221,21 +219,21 @@ png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
+ png_debug(1, "in png_get_pixel_aspect_ratio");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
-
if (info_ptr->x_pixels_per_unit != 0)
- return ((float)((float)info_ptr->y_pixels_per_unit
- /(float)info_ptr->x_pixels_per_unit));
+ return (float)info_ptr->y_pixels_per_unit
+ / (float)info_ptr->x_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return ((float)0.0);
+ return (float)0.0;
}
#endif
@@ -245,6 +243,8 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
png_const_inforp info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
+ png_debug(1, "in png_get_pixel_aspect_ratio_fixed");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0 &&
info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
@@ -253,8 +253,6 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
{
png_fixed_point res;
- png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
-
/* The following casts work because a PNG 4 byte integer only has a valid
* range of 0..2^31-1; otherwise the cast might overflow.
*/
@@ -275,80 +273,80 @@ png_int_32 PNGAPI
png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
+ png_debug(1, "in png_get_x_offset_microns");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
-
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
- return (info_ptr->x_offset);
+ return info_ptr->x_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
png_int_32 PNGAPI
png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
+ png_debug(1, "in png_get_y_offset_microns");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
-
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
- return (info_ptr->y_offset);
+ return info_ptr->y_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
png_int_32 PNGAPI
png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
+ png_debug(1, "in png_get_x_offset_pixels");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
-
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
- return (info_ptr->x_offset);
+ return info_ptr->x_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
png_int_32 PNGAPI
png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
+ png_debug(1, "in png_get_y_offset_pixels");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
- png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
-
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
- return (info_ptr->y_offset);
+ return info_ptr->y_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (0);
+ return 0;
}
#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
@@ -462,11 +460,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_uint_32 retval = 0;
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
- png_debug1(1, "in %s retrieval function", "pHYs");
-
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
@@ -492,7 +490,7 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
- return (retval);
+ return retval;
}
#endif /* pHYs */
#endif /* INCH_CONVERSIONS */
@@ -506,9 +504,9 @@ png_byte PNGAPI
png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->channels);
+ return info_ptr->channels;
- return (0);
+ return 0;
}
#ifdef PNG_READ_SUPPORTED
@@ -516,9 +514,9 @@ png_const_bytep PNGAPI
png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->signature);
+ return info_ptr->signature;
- return (NULL);
+ return NULL;
}
#endif
@@ -527,17 +525,17 @@ png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
png_color_16p *background)
{
+ png_debug1(1, "in %s retrieval function", "bKGD");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 &&
background != NULL)
{
- png_debug1(1, "in %s retrieval function", "bKGD");
-
*background = &(info_ptr->background);
- return (PNG_INFO_bKGD);
+ return PNG_INFO_bKGD;
}
- return (0);
+ return 0;
}
#endif
@@ -552,6 +550,8 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *white_x, double *white_y, double *red_x, double *red_y,
double *green_x, double *green_y, double *blue_x, double *blue_y)
{
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
/* Quiet API change: this code used to only return the end points if a cHRM
* chunk was present, but the end points can also come from iCCP or sRGB
* chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
@@ -561,8 +561,6 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
- png_debug1(1, "in %s retrieval function", "cHRM");
-
if (white_x != NULL)
*white_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
@@ -587,10 +585,10 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
"cHRM blue Y");
- return (PNG_INFO_cHRM);
+ return PNG_INFO_cHRM;
}
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
@@ -599,11 +597,11 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z)
{
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
- png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
-
if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
"cHRM red X");
@@ -631,10 +629,10 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (blue_Z != NULL)
*blue_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
- return (PNG_INFO_cHRM);
+ return PNG_INFO_cHRM;
}
- return (0);
+ return 0;
}
# endif
@@ -647,11 +645,11 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z)
{
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
- png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
-
if (int_red_X != NULL)
*int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
if (int_red_Y != NULL)
@@ -670,10 +668,10 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
if (int_blue_Z != NULL)
*int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
- return (PNG_INFO_cHRM);
+ return PNG_INFO_cHRM;
}
- return (0);
+ return 0;
}
png_uint_32 PNGAPI
@@ -703,10 +701,10 @@ png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*blue_x = info_ptr->colorspace.end_points_xy.bluex;
if (blue_y != NULL)
*blue_y = info_ptr->colorspace.end_points_xy.bluey;
- return (PNG_INFO_cHRM);
+ return PNG_INFO_cHRM;
}
- return (0);
+ return 0;
}
# endif
#endif
@@ -724,10 +722,10 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
file_gamma != NULL)
{
*file_gamma = info_ptr->colorspace.gamma;
- return (PNG_INFO_gAMA);
+ return PNG_INFO_gAMA;
}
- return (0);
+ return 0;
}
# endif
@@ -744,10 +742,10 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
"png_get_gAMA");
- return (PNG_INFO_gAMA);
+ return PNG_INFO_gAMA;
}
- return (0);
+ return 0;
}
# endif
#endif
@@ -763,10 +761,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
(info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
{
*file_srgb_intent = info_ptr->colorspace.rendering_intent;
- return (PNG_INFO_sRGB);
+ return PNG_INFO_sRGB;
}
- return (0);
+ return 0;
}
#endif
@@ -790,10 +788,10 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
*/
if (compression_type != NULL)
*compression_type = PNG_COMPRESSION_TYPE_BASE;
- return (PNG_INFO_iCCP);
+ return PNG_INFO_iCCP;
}
- return (0);
+ return 0;
}
#endif
@@ -803,13 +801,15 @@ int PNGAPI
png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
png_sPLT_tpp spalettes)
{
+ png_debug1(1, "in %s retrieval function", "sPLT");
+
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
{
*spalettes = info_ptr->splt_palettes;
return info_ptr->splt_palettes_num;
}
- return (0);
+ return 0;
}
#endif
@@ -835,10 +835,10 @@ png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
*num_exif = info_ptr->num_exif;
*exif = info_ptr->exif;
- return (PNG_INFO_eXIf);
+ return PNG_INFO_eXIf;
}
- return (0);
+ return 0;
}
#endif
@@ -853,10 +853,10 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
{
*hist = info_ptr->hist;
- return (PNG_INFO_hIST);
+ return PNG_INFO_hIST;
}
- return (0);
+ return 0;
}
#endif
@@ -869,7 +869,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "IHDR");
if (png_ptr == NULL || info_ptr == NULL)
- return (0);
+ return 0;
if (width != NULL)
*width = info_ptr->width;
@@ -901,7 +901,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
info_ptr->compression_type, info_ptr->filter_type);
- return (1);
+ return 1;
}
#ifdef PNG_oFFs_SUPPORTED
@@ -918,10 +918,10 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
*offset_x = info_ptr->x_offset;
*offset_y = info_ptr->y_offset;
*unit_type = (int)info_ptr->offset_unit_type;
- return (PNG_INFO_oFFs);
+ return PNG_INFO_oFFs;
}
- return (0);
+ return 0;
}
#endif
@@ -945,10 +945,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
*nparams = (int)info_ptr->pcal_nparams;
*units = info_ptr->pcal_units;
*params = info_ptr->pcal_params;
- return (PNG_INFO_pCAL);
+ return PNG_INFO_pCAL;
}
- return (0);
+ return 0;
}
#endif
@@ -960,6 +960,8 @@ png_uint_32 PNGAPI
png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_fixed_point *width, png_fixed_point *height)
{
+ png_debug1(1, "in %s retrieval function", "sCAL");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
@@ -971,10 +973,10 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
"sCAL height");
- return (PNG_INFO_sCAL);
+ return PNG_INFO_sCAL;
}
- return(0);
+ return 0;
}
# endif /* FLOATING_ARITHMETIC */
# endif /* FIXED_POINT */
@@ -983,32 +985,36 @@ png_uint_32 PNGAPI
png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, double *width, double *height)
{
+ png_debug1(1, "in %s retrieval function", "sCAL(float)");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
*unit = info_ptr->scal_unit;
*width = atof(info_ptr->scal_s_width);
*height = atof(info_ptr->scal_s_height);
- return (PNG_INFO_sCAL);
+ return PNG_INFO_sCAL;
}
- return(0);
+ return 0;
}
# endif /* FLOATING POINT */
png_uint_32 PNGAPI
png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_charpp width, png_charpp height)
{
+ png_debug1(1, "in %s retrieval function", "sCAL(str)");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
*unit = info_ptr->scal_unit;
*width = info_ptr->scal_s_width;
*height = info_ptr->scal_s_height;
- return (PNG_INFO_sCAL);
+ return PNG_INFO_sCAL;
}
- return(0);
+ return 0;
}
#endif /* sCAL */
@@ -1043,7 +1049,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
- return (retval);
+ return retval;
}
#endif /* pHYs */
@@ -1059,10 +1065,10 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
*palette = info_ptr->palette;
*num_palette = info_ptr->num_palette;
png_debug1(3, "num_palette = %d", *num_palette);
- return (PNG_INFO_PLTE);
+ return PNG_INFO_PLTE;
}
- return (0);
+ return 0;
}
#ifdef PNG_sBIT_SUPPORTED
@@ -1076,10 +1082,10 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
{
*sig_bit = &(info_ptr->sig_bit);
- return (PNG_INFO_sBIT);
+ return PNG_INFO_sBIT;
}
- return (0);
+ return 0;
}
#endif
@@ -1090,7 +1096,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
{
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
{
- png_debug1(1, "in 0x%lx retrieval function",
+ png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx",
(unsigned long)png_ptr->chunk_name);
if (text_ptr != NULL)
@@ -1105,7 +1111,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
if (num_text != NULL)
*num_text = 0;
- return(0);
+ return 0;
}
#endif
@@ -1120,10 +1126,10 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
{
*mod_time = &(info_ptr->mod_time);
- return (PNG_INFO_tIME);
+ return PNG_INFO_tIME;
}
- return (0);
+ return 0;
}
#endif
@@ -1133,11 +1139,12 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
{
png_uint_32 retval = 0;
+
+ png_debug1(1, "in %s retrieval function", "tRNS");
+
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_tRNS) != 0)
{
- png_debug1(1, "in %s retrieval function", "tRNS");
-
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (trans_alpha != NULL)
@@ -1169,7 +1176,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
}
}
- return (retval);
+ return retval;
}
#endif
@@ -1184,7 +1191,7 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
return info_ptr->unknown_chunks_num;
}
- return (0);
+ return 0;
}
#endif
@@ -1280,7 +1287,7 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return png_ptr->num_palette_max;
- return (-1);
+ return -1;
}
# endif
#endif
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
index e98d49cf0cc..e238ccdb9a4 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
@@ -31,7 +31,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*/
-/* libpng version 1.6.40 */
+/* libpng version 1.6.43 */
/* Copyright (c) 2018-2023 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
index a98b2013256..816631cae18 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -173,10 +173,10 @@ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
num_to_check);
png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
{
if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
png_error(png_ptr, "Not a PNG file");
else
@@ -322,6 +322,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
}
+#endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+ else if (png_ptr->chunk_name == png_eXIf)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
else if (chunk_name == png_sRGB)
@@ -1117,7 +1125,7 @@ png_voidp PNGAPI
png_get_progressive_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return (NULL);
+ return NULL;
return png_ptr->io_ptr;
}
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
index 914d0b97b1d..18424542b00 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2023 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -64,7 +64,7 @@
* still required (as of 2011-05-02.)
*/
#ifndef _POSIX_SOURCE
-# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#endif
#ifndef PNG_VERSION_INFO_ONLY
@@ -218,13 +218,27 @@
#endif /* PNG_ARM_NEON_OPT > 0 */
#ifndef PNG_MIPS_MSA_OPT
-# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \
+ defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# define PNG_MIPS_MSA_OPT 2
# else
# define PNG_MIPS_MSA_OPT 0
# endif
#endif
+#ifndef PNG_MIPS_MMI_OPT
+# ifdef PNG_MIPS_MMI
+# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \
+ defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+# define PNG_MIPS_MMI_OPT 1
+# else
+# define PNG_MIPS_MMI_OPT 0
+# endif
+# else
+# define PNG_MIPS_MMI_OPT 0
+# endif
+#endif
+
#ifndef PNG_POWERPC_VSX_OPT
# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
# define PNG_POWERPC_VSX_OPT 2
@@ -233,13 +247,21 @@
# endif
#endif
+#ifndef PNG_LOONGARCH_LSX_OPT
+# if defined(__loongarch_sx)
+# define PNG_LOONGARCH_LSX_OPT 1
+# else
+# define PNG_LOONGARCH_LSX_OPT 0
+# endif
+#endif
+
#ifndef PNG_INTEL_SSE_OPT
# ifdef PNG_INTEL_SSE
/* Only check for SSE if the build configuration has been modified to
* enable SSE optimizations. This means that these optimizations will
* be off by default. See contrib/intel for more details.
*/
-# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
+# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_OPT 1
@@ -276,7 +298,6 @@
#endif
#if PNG_MIPS_MSA_OPT > 0
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# if defined(__mips_msa)
# if defined(__clang__)
@@ -292,11 +313,28 @@
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# define PNG_MIPS_MSA_IMPLEMENTATION 1
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
# endif
#else
# define PNG_MIPS_MSA_IMPLEMENTATION 0
#endif /* PNG_MIPS_MSA_OPT > 0 */
+#if PNG_MIPS_MMI_OPT > 0
+# ifndef PNG_MIPS_MMI_IMPLEMENTATION
+# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64)
+# define PNG_MIPS_MMI_IMPLEMENTATION 2
+# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */
+# define PNG_MIPS_MMI_IMPLEMENTATION 0
+# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */
+# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */
+
+# if PNG_MIPS_MMI_IMPLEMENTATION > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
+# endif
+#else
+# define PNG_MIPS_MMI_IMPLEMENTATION 0
+#endif /* PNG_MIPS_MMI_OPT > 0 */
+
#if PNG_POWERPC_VSX_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
# define PNG_POWERPC_VSX_IMPLEMENTATION 1
@@ -304,6 +342,12 @@
# define PNG_POWERPC_VSX_IMPLEMENTATION 0
#endif
+#if PNG_LOONGARCH_LSX_OPT > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx
+# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1
+#else
+# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0
+#endif
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
@@ -542,18 +586,8 @@
*/
# include
-# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
- defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
- /* We need to check that hasn't already been included earlier
- * as it seems it doesn't agree with , yet we should really use
- * if possible.
- */
-# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
-# include
-# endif
-# else
-# include
-# endif
+# include
+
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881
@@ -1334,7 +1368,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
-#if PNG_MIPS_MSA_OPT > 0
+#if PNG_MIPS_MSA_IMPLEMENTATION == 1
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
@@ -1351,6 +1385,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
+#if PNG_MIPS_MMI_IMPLEMENTATION > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
#if PNG_POWERPC_VSX_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
@@ -1383,6 +1434,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
+#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
/* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
png_row_infop row_info),PNG_EMPTY);
@@ -2122,17 +2190,27 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
-#if PNG_MIPS_MSA_OPT > 0
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
+#if PNG_MIPS_MSA_IMPLEMENTATION == 1
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
+# if PNG_MIPS_MMI_IMPLEMENTATION > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+# endif
+
# if PNG_INTEL_SSE_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
# endif
#endif
+#if PNG_LOONGARCH_LSX_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
png_const_charp key, png_bytep new_key), PNG_EMPTY);
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
index 3631e60f36b..e9e94477545 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2019 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -596,7 +596,11 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
#endif
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
- if (png_ptr->transformations)
+ if (png_ptr->transformations
+# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ || png_ptr->num_palette_max >= 0
+# endif
+ )
png_do_read_transformations(png_ptr, &row_info);
#endif
@@ -813,7 +817,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Report invalid palette index; added at libng-1.5.10 */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- png_ptr->num_palette_max > png_ptr->num_palette)
+ png_ptr->num_palette_max >= png_ptr->num_palette)
png_benign_error(png_ptr, "Read palette index exceeding num_palette");
#endif
@@ -1077,6 +1081,8 @@ void PNGAPI
png_read_png(png_structrp png_ptr, png_inforp info_ptr,
int transforms, voidp params)
{
+ png_debug(1, "in png_read_png");
+
if (png_ptr == NULL || info_ptr == NULL)
return;
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
index 843eb5fff2a..a393de4b79d 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2019 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -318,21 +318,20 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
int compose = 0;
png_fixed_point file_gamma;
- png_debug(1, "in png_set_alpha_mode");
+ png_debug(1, "in png_set_alpha_mode_fixed");
if (png_rtran_ok(png_ptr, 0) == 0)
return;
output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
- /* Validate the value to ensure it is in a reasonable range. The value
+ /* Validate the value to ensure it is in a reasonable range. The value
* is expected to be 1 or greater, but this range test allows for some
- * viewing correction values. The intent is to weed out users of this API
- * who use the inverse of the gamma value accidentally! Since some of these
- * values are reasonable this may have to be changed:
+ * viewing correction values. The intent is to weed out the API users
+ * who might use the inverse of the gamma value accidentally!
*
- * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit
- * gamma of 36, and its reciprocal.)
+ * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate
+ * the optimal 16-bit gamma of 36 and its reciprocal.
*/
if (output_gamma < 1000 || output_gamma > 10000000)
png_error(png_ptr, "output gamma out of expected range");
@@ -469,7 +468,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
int i;
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)num_palette);
for (i = 0; i < num_palette; i++)
png_ptr->quantize_index[i] = (png_byte)i;
}
@@ -486,7 +485,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize an array to sort colors */
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)num_palette);
/* Initialize the quantize_sort array */
for (i = 0; i < num_palette; i++)
@@ -620,11 +619,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)((png_uint_32)num_palette *
- (sizeof (png_byte))));
+ (png_alloc_size_t)num_palette);
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)((png_uint_32)num_palette *
- (sizeof (png_byte))));
+ (png_alloc_size_t)num_palette);
/* Initialize the sort array */
for (i = 0; i < num_palette; i++)
@@ -789,12 +786,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
size_t num_entries = ((size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
- (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
+ (png_alloc_size_t)(num_entries));
- distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
- (sizeof (png_byte))));
+ distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries);
- memset(distance, 0xff, num_entries * (sizeof (png_byte)));
+ memset(distance, 0xff, num_entries);
for (i = 0; i < num_palette; i++)
{
@@ -998,7 +994,7 @@ void PNGFAPI
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
png_fixed_point red, png_fixed_point green)
{
- png_debug(1, "in png_set_rgb_to_gray");
+ png_debug(1, "in png_set_rgb_to_gray_fixed");
/* Need the IHDR here because of the check on color_type below. */
/* TODO: fix this */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
index 524297c5a10..5280140d12b 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -54,7 +54,7 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
if (uval > PNG_UINT_31_MAX)
png_error(png_ptr, "PNG unsigned integer out of range");
- return (uval);
+ return uval;
}
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
@@ -168,7 +168,7 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
{
if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
png_error(png_ptr, "Not a PNG file");
else
png_error(png_ptr, "PNG file corrupted by ASCII conversion");
@@ -199,7 +199,7 @@ png_read_chunk_header(png_structrp png_ptr)
/* Put the chunk name into png_ptr->chunk_name. */
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
- png_debug2(0, "Reading %lx chunk, length = %lu",
+ png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu",
(unsigned long)png_ptr->chunk_name, (unsigned long)length);
/* Reset the crc and run it over the chunk name. */
@@ -266,10 +266,10 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
else
png_chunk_error(png_ptr, "CRC error");
- return (1);
+ return 1;
}
- return (0);
+ return 0;
}
/* Compare the CRC stored in the PNG file with that calculated by libpng from
@@ -305,11 +305,11 @@ png_crc_error(png_structrp png_ptr)
if (need_crc != 0)
{
crc = png_get_uint_32(crc_bytes);
- return ((int)(crc != png_ptr->crc));
+ return crc != png_ptr->crc;
}
else
- return (0);
+ return 0;
}
#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
@@ -449,8 +449,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
-#if ZLIB_VERNUM >= 0x1290 && \
- defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
+#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
/* Turn off validation of the ADLER32 checksum in IDAT chunks */
ret = inflateValidate(&png_ptr->zstream, 0);
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
index 62612a02278..f53ab6fa1d1 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018-2023 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -791,11 +791,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
{
int i;
- png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U :
- (unsigned long)png_ptr->chunk_name);
+ png_debug1(1, "in text storage function, chunk typeid = 0x%lx",
+ png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name);
if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
- return(0);
+ return 0;
/* Make sure we have enough space in the "text" array in info_struct
* to hold all of the incoming text_ptr objects. This compare can't overflow
@@ -975,7 +975,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
}
- return(0);
+ return 0;
}
#endif
@@ -1091,6 +1091,8 @@ png_set_sPLT(png_const_structrp png_ptr,
{
png_sPLT_tp np;
+ png_debug1(1, "in %s storage function", "sPLT");
+
if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
return;
@@ -1565,7 +1567,7 @@ void PNGAPI
png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytepp row_pointers)
{
- png_debug1(1, "in %s storage function", "rows");
+ png_debug(1, "in png_set_rows");
if (png_ptr == NULL || info_ptr == NULL)
return;
@@ -1584,6 +1586,8 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
void PNGAPI
png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
{
+ png_debug(1, "in png_set_compression_buffer_size");
+
if (png_ptr == NULL)
return;
@@ -1655,6 +1659,8 @@ void PNGAPI
png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
png_uint_32 user_height_max)
{
+ png_debug(1, "in png_set_user_limits");
+
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
* regardless of dimensions, set both limits to 0x7fffffff.
@@ -1670,6 +1676,8 @@ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
void PNGAPI
png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
{
+ png_debug(1, "in png_set_chunk_cache_max");
+
if (png_ptr != NULL)
png_ptr->user_chunk_cache_max = user_chunk_cache_max;
}
@@ -1679,6 +1687,8 @@ void PNGAPI
png_set_chunk_malloc_max(png_structrp png_ptr,
png_alloc_size_t user_chunk_malloc_max)
{
+ png_debug(1, "in png_set_chunk_malloc_max");
+
if (png_ptr != NULL)
png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
}
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
index 89a62191b6f..2350057e70e 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
@@ -29,7 +29,7 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -131,10 +131,10 @@ png_set_interlace_handling(png_structrp png_ptr)
if (png_ptr != 0 && png_ptr->interlaced != 0)
{
png_ptr->transformations |= PNG_INTERLACE;
- return (7);
+ return 7;
}
- return (1);
+ return 1;
}
#endif
@@ -526,6 +526,8 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
+ png_debug(1, "in png_do_strip_channel");
+
/* At the start sp will point to the first byte to copy and dp to where
* it is copied to. ep always points just beyond the end of the row, so
* the loop simply copies (channels-1) channels until sp reaches ep.
@@ -726,6 +728,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
void /* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
{
+ png_debug(1, "in png_do_check_palette_indexes");
+
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
{
@@ -736,7 +740,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* forms produced on either GCC or MSVC.
*/
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
- png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
+ png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
switch (row_info->bit_depth)
{
@@ -861,7 +865,7 @@ png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return (NULL);
+ return NULL;
return png_ptr->user_transform_ptr;
}
diff --git a/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java b/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java
index 2f31611cf5f..3daf9b2a8b8 100644
--- a/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java
+++ b/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.PosixFilePermission;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -58,6 +60,7 @@
* The restore token allows the ScreenCast session to be restored
* with previously granted screen access permissions.
*/
+@SuppressWarnings("removal")
final class TokenStorage {
private TokenStorage() {}
@@ -69,8 +72,24 @@ private TokenStorage() {}
private static final Path PROPS_PATH;
private static final Path PROP_FILENAME;
+ private static void doPrivilegedRunnable(Runnable runnable) {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ @Override
+ public Void run() {
+ runnable.run();
+ return null;
+ }
+ });
+ }
+
static {
- PROPS_PATH = setupPath();
+ PROPS_PATH = AccessController.doPrivileged(new PrivilegedAction() {
+ @Override
+ public Path run() {
+ return setupPath();
+ }
+ });
+
if (PROPS_PATH != null) {
PROP_FILENAME = PROPS_PATH.getFileName();
if (SCREENCAST_DEBUG) {
@@ -192,9 +211,9 @@ public void run() {
}
if (kind == ENTRY_CREATE) {
- setFilePermission(PROPS_PATH);
+ doPrivilegedRunnable(() -> setFilePermission(PROPS_PATH));
} else if (kind == ENTRY_MODIFY) {
- readTokens(PROPS_PATH);
+ doPrivilegedRunnable(() -> readTokens(PROPS_PATH));
} else if (kind == ENTRY_DELETE) {
synchronized (PROPS) {
PROPS.clear();
@@ -207,24 +226,31 @@ public void run() {
}
}
+ private static WatchService watchService;
+
private static void setupWatch() {
- try {
- WatchService watchService =
- FileSystems.getDefault().newWatchService();
+ doPrivilegedRunnable(() -> {
+ try {
+ watchService =
+ FileSystems.getDefault().newWatchService();
- PROPS_PATH
- .getParent()
- .register(watchService,
- ENTRY_CREATE,
- ENTRY_DELETE,
- ENTRY_MODIFY);
+ PROPS_PATH
+ .getParent()
+ .register(watchService,
+ ENTRY_CREATE,
+ ENTRY_DELETE,
+ ENTRY_MODIFY);
- new WatcherThread(watchService).start();
- } catch (Exception e) {
- if (SCREENCAST_DEBUG) {
- System.err.printf("Token storage: failed to setup " +
- "file watch %s\n", e);
+ } catch (Exception e) {
+ if (SCREENCAST_DEBUG) {
+ System.err.printf("Token storage: failed to setup " +
+ "file watch %s\n", e);
+ }
}
+ });
+
+ if (watchService != null) {
+ new WatcherThread(watchService).start();
}
}
@@ -276,7 +302,7 @@ private static void storeTokenFromNative(String oldToken,
}
if (changed) {
- store("save tokens");
+ doPrivilegedRunnable(() -> store("save tokens"));
}
}
}
@@ -331,7 +357,7 @@ static Set getTokens(List affectedScreenBounds) {
.toList();
}
- removeMalformedRecords(malformed);
+ doPrivilegedRunnable(() -> removeMalformedRecords(malformed));
// 1. Try to find exact matches
for (TokenItem tokenItem : allTokenItems) {
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java b/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java
index 61972bf4ed5..7c0d8c1ea4d 100644
--- a/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java
+++ b/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -100,21 +100,30 @@ public static boolean isXPStyleEnabled() {
return xpStyleEnabled;
}
- private static Long openThemeImpl(String widget, int dpi) {
- Long theme;
+ private static long openThemeImpl(String widget, int dpi) {
+ long theme;
int i = widget.indexOf("::");
if (i > 0) {
// We're using the syntax "subAppName::controlName" here, as used by msstyles.
// See documentation for SetWindowTheme on MSDN.
setWindowTheme(widget.substring(0, i));
- theme = openTheme(widget.substring(i + 2), dpi);
+ theme = getOpenThemeValue(widget.substring(i + 2), dpi);
setWindowTheme(null);
} else {
- theme = openTheme(widget, dpi);
+ theme = getOpenThemeValue(widget, dpi);
}
return theme;
}
+ private static long getOpenThemeValue(String widget, int dpi) {
+ long theme;
+ theme = openTheme(widget, dpi);
+ if (theme == 0) {
+ theme = openTheme(widget, defaultDPI);
+ }
+ return theme;
+ }
+
// this should be called only with writeLock held
private static Long getThemeImpl(String widget, int dpi) {
return dpiAwareWidgetToTheme.computeIfAbsent(dpi, key -> new HashMap<>())
diff --git a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
index b3f13a5bf82..335281ad5d7 100644
--- a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -119,17 +119,6 @@ static jstring lsSize;
static jstring lsType;
static jstring lsDate;
-// Some macros from awt.h, because it is not included in release
-#ifndef IS_WIN2000
-#define IS_WIN2000 (LOBYTE(LOWORD(::GetVersion())) >= 5)
-#endif
-#ifndef IS_WINXP
-#define IS_WINXP ((IS_WIN2000 && HIBYTE(LOWORD(::GetVersion())) >= 1) || LOBYTE(LOWORD(::GetVersion())) > 5)
-#endif
-#ifndef IS_WINVISTA
-#define IS_WINVISTA (!(::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion())) >= 6)
-#endif
-
extern "C" {
@@ -1090,12 +1079,10 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
// XP supports alpha in some icons, and depending on device.
// This should take precedence over the icon mask bits.
BOOL hasAlpha = FALSE;
- if (IS_WINXP) {
- for (int i = 0; i < nBits; i++) {
- if ((colorBits[i] & 0xff000000) != 0) {
- hasAlpha = TRUE;
- break;
- }
+ for (int i = 0; i < nBits; i++) {
+ if ((colorBits[i] & 0xff000000) != 0) {
+ hasAlpha = TRUE;
+ break;
}
}
if (!hasAlpha) {
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java
index 6e6182a1fb2..81acd83c423 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -89,7 +89,6 @@ private PasswordAuthentication getCredentials(String header,
InetSocketAddress proxyAddress;
if (proxy && (proxyAddress = req.proxy()) != null) {
// request sent to server through proxy
- proxyAddress = req.proxy();
host = proxyAddress.getHostString();
port = proxyAddress.getPort();
protocol = "http"; // we don't support https connection to proxy
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
index c4a7abe2816..1bb520a6fb1 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1724,9 +1724,10 @@ protected void unregister() {
private static final VarHandle DEREGISTERED;
static {
try {
- STREAM_STATE = MethodHandles.lookup()
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ STREAM_STATE = lookup
.findVarHandle(Stream.class, "streamState", int.class);
- DEREGISTERED = MethodHandles.lookup()
+ DEREGISTERED = lookup
.findVarHandle(Stream.class, "deRegistered", boolean.class);
} catch (Exception x) {
throw new ExceptionInInitializerError(x);
diff --git a/src/java.sql/share/classes/java/sql/DatabaseMetaData.java b/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
index 6f63c2989b8..f4cb8787b5f 100644
--- a/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
+++ b/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1215,7 +1215,7 @@ boolean dataDefinitionIgnoredInTransactions()
* Only procedure descriptions matching the schema and
* procedure name criteria are returned. They are ordered by
* {@code PROCEDURE_CAT}, {@code PROCEDURE_SCHEM},
- * {@code PROCEDURE_NAME} and {@code SPECIFIC_ NAME}.
+ * {@code PROCEDURE_NAME} and {@code SPECIFIC_NAME}.
*
* Each procedure description has the following columns:
*
@@ -3289,7 +3289,7 @@ ResultSet getClientInfoProperties()
* function name criteria are returned. They are ordered by
* {@code FUNCTION_CAT}, {@code FUNCTION_SCHEM},
* {@code FUNCTION_NAME} and
- * {@code SPECIFIC_ NAME}.
+ * {@code SPECIFIC_NAME}.
*
* Each function description has the following columns:
*
@@ -3339,7 +3339,7 @@ ResultSet getFunctions(String catalog, String schemaPattern,
* parameter name criteria are returned. They are ordered by
* {@code FUNCTION_CAT}, {@code FUNCTION_SCHEM},
* {@code FUNCTION_NAME} and
- * {@code SPECIFIC_ NAME}. Within this, the return value,
+ * {@code SPECIFIC_NAME}. Within this, the return value,
* if any, is first. Next are the parameter descriptions in call
* order. The column descriptions follow in column number order.
*
@@ -3358,7 +3358,7 @@ ResultSet getFunctions(String catalog, String schemaPattern,
* functionColumnIn - IN parameter
* functionColumnInOut - INOUT parameter
* functionColumnOut - OUT parameter
- * functionColumnReturn - function return value
+ * functionReturn - function return value
* functionColumnResult - Indicates that the parameter or column
* is a column in the {@code ResultSet}
*
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
index 081367fa26a..45c76071f8b 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1059,6 +1059,11 @@ public String getText() {
return "";
}
+ @Override
+ public JCDiagnostic.DiagnosticPosition getPos() {
+ return null;
+ }
+
@Override
public int getSourcePos(int index) {
return offset + index;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java
index 94d121ad04d..9fba9b5318b 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,10 +52,15 @@ public static DeferredLintHandler instance(Context context) {
return instance;
}
+ /** The Lint to use when {@link #immediate(Lint)} is used,
+ * instead of {@link #setPos(DiagnosticPosition)}. */
+ private Lint immediateLint;
+
@SuppressWarnings("this-escape")
protected DeferredLintHandler(Context context) {
context.put(deferredLintHandlerKey, this);
this.currentPos = IMMEDIATE_POSITION;
+ immediateLint = Lint.instance(context);
}
/**An interface for deferred lint reporting - loggers passed to
@@ -63,7 +68,7 @@ protected DeferredLintHandler(Context context) {
* {@link #flush(DiagnosticPosition) } is invoked.
*/
public interface LintLogger {
- void report();
+ void report(Lint lint);
}
private DiagnosticPosition currentPos;
@@ -77,7 +82,7 @@ public interface LintLogger {
*/
public void report(LintLogger logger) {
if (currentPos == IMMEDIATE_POSITION) {
- logger.report();
+ logger.report(immediateLint);
} else {
ListBuffer loggers = loggersQueue.get(currentPos);
if (loggers == null) {
@@ -89,11 +94,11 @@ public void report(LintLogger logger) {
/**Invoke all {@link LintLogger}s that were associated with the provided {@code pos}.
*/
- public void flush(DiagnosticPosition pos) {
+ public void flush(DiagnosticPosition pos, Lint lint) {
ListBuffer loggers = loggersQueue.get(pos);
if (loggers != null) {
for (LintLogger lintLogger : loggers) {
- lintLogger.report();
+ lintLogger.report(lint);
}
loggersQueue.remove(pos);
}
@@ -112,7 +117,8 @@ public DiagnosticPosition setPos(DiagnosticPosition currentPos) {
/**{@link LintLogger}s passed to subsequent invocations of
* {@link #report(LintLogger) } will be invoked immediately.
*/
- public DiagnosticPosition immediate() {
+ public DiagnosticPosition immediate(Lint lint) {
+ immediateLint = lint;
return setPos(IMMEDIATE_POSITION);
}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java
index c19480728d1..67f14941532 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -180,6 +180,12 @@ public enum LintCategory {
*/
CLASSFILE("classfile"),
+ /**
+ * Warn about"dangling" documentation comments,
+ * not attached to any declaration.
+ */
+ DANGLING_DOC_COMMENTS("dangling-doc-comments"),
+
/**
* Warn about use of deprecated items.
*/
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
index c08f33bf5e2..c582209cfe2 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
@@ -1135,6 +1135,7 @@ private String className(Symbol sym, boolean longform) {
s += String.valueOf(sym.hashCode());
return s;
} else if (longform) {
+ sym.apiComplete();
return sym.getQualifiedName().toString();
} else {
return sym.name.toString();
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
index 71c9d59cb27..40a2da35488 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -254,7 +254,7 @@ public void annotateLater(List annotations, Env local
DiagnosticPosition prevLintPos =
deferPos != null
? deferredLintHandler.setPos(deferPos)
- : deferredLintHandler.immediate();
+ : deferredLintHandler.immediate(lint);
Lint prevLint = deferPos != null ? null : chk.setLint(lint);
try {
if (s.hasAnnotations() && annotations.nonEmpty())
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
index 2692e573ba6..9017ed72ed9 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -990,7 +990,7 @@ public void visitMethodDef(JCMethodDecl tree) {
env.info.ctorPrologue = false;
MethodSymbol prevMethod = chk.setMethod(m);
try {
- deferredLintHandler.flush(tree.pos());
+ deferredLintHandler.flush(tree.pos(), lint);
chk.checkDeprecatedAnnotation(tree.pos(), m);
@@ -1295,7 +1295,7 @@ public void visitVarDef(JCVariableDecl tree) {
try {
v.getConstValue(); // ensure compile-time constant initializer is evaluated
- deferredLintHandler.flush(tree.pos());
+ deferredLintHandler.flush(tree.pos(), lint);
chk.checkDeprecatedAnnotation(tree.pos(), v);
if (tree.init != null) {
@@ -5318,7 +5318,7 @@ private void attribWithLint(TypeSymbol sym, Consumer> attrib) {
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
try {
- deferredLintHandler.flush(env.tree.pos());
+ deferredLintHandler.flush(env.tree.pos(), lint);
attrib.accept(env);
} finally {
log.useSource(prev);
@@ -5493,7 +5493,7 @@ void attribClass(ClassSymbol c) throws CompletionFailure {
}
}
- deferredLintHandler.flush(env.tree);
+ deferredLintHandler.flush(env.tree, env.info.lint);
env.info.returnResult = null;
// java.lang.Enum may not be subclassed by a non-enum
if (st.tsym == syms.enumSym &&
@@ -5548,7 +5548,7 @@ public void visitModuleDef(JCModuleDecl tree) {
chk.checkDeprecatedAnnotation(tree, msym);
try {
- deferredLintHandler.flush(tree.pos());
+ deferredLintHandler.flush(tree.pos(), lint);
} finally {
chk.setLint(prevLint);
}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
index 055d11a9502..4efae80426d 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -673,7 +673,7 @@ public void checkRedundantCast(Env env, final JCTypeCast tree) {
&& types.isSameType(tree.expr.type, tree.clazz.type)
&& !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
&& !is292targetTypeCast(tree)) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.CAST))
log.warning(LintCategory.CAST,
tree.pos(), Warnings.RedundantCast(tree.clazz.type));
@@ -1433,7 +1433,7 @@ && checkDisjoint(pos, flags,
private void warnOnExplicitStrictfp(DiagnosticPosition pos) {
DiagnosticPosition prevLintPos = deferredLintHandler.setPos(pos);
try {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.STRICTFP)) {
log.warning(LintCategory.STRICTFP,
pos, Warnings.Strictfp); }
@@ -3907,13 +3907,13 @@ void checkDeprecated(Supplier pos, final Symbol other, final
|| s.isDeprecated() && !other.isDeprecated())
&& (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)
&& s.kind != Kind.PCK) {
- deferredLintHandler.report(() -> warnDeprecated(pos.get(), s));
+ deferredLintHandler.report(_l -> warnDeprecated(pos.get(), s));
}
}
void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
if ((s.flags() & PROPRIETARY) != 0) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
log.mandatoryWarning(pos, Warnings.SunProprietary(s));
});
}
@@ -3932,10 +3932,10 @@ void checkPreview(DiagnosticPosition pos, Symbol other, Symbol s) {
log.error(pos, Errors.IsPreview(s));
} else {
preview.markUsesPreview(pos);
- deferredLintHandler.report(() -> warnPreviewAPI(pos, Warnings.IsPreview(s)));
+ deferredLintHandler.report(_l -> warnPreviewAPI(pos, Warnings.IsPreview(s)));
}
} else {
- deferredLintHandler.report(() -> warnPreviewAPI(pos, Warnings.IsPreviewReflective(s)));
+ deferredLintHandler.report(_l -> warnPreviewAPI(pos, Warnings.IsPreviewReflective(s)));
}
}
if (preview.declaredUsingPreviewFeature(s)) {
@@ -3944,14 +3944,14 @@ void checkPreview(DiagnosticPosition pos, Symbol other, Symbol s) {
//If "s" is compiled from source, then there was an error for it already;
//if "s" is from classfile, there already was an error for the classfile.
preview.markUsesPreview(pos);
- deferredLintHandler.report(() -> warnDeclaredUsingPreview(pos, s));
+ deferredLintHandler.report(_l -> warnDeclaredUsingPreview(pos, s));
}
}
}
void checkRestricted(DiagnosticPosition pos, Symbol s) {
if (s.kind == MTH && (s.flags() & RESTRICTED) != 0) {
- deferredLintHandler.report(() -> warnRestrictedAPI(pos, s));
+ deferredLintHandler.report(_l -> warnRestrictedAPI(pos, s));
}
}
@@ -4203,7 +4203,7 @@ void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
int opc = ((OperatorSymbol)operator).opcode;
if (opc == ByteCodes.idiv || opc == ByteCodes.imod
|| opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
- deferredLintHandler.report(() -> warnDivZero(pos));
+ deferredLintHandler.report(_l -> warnDivZero(pos));
}
}
}
@@ -4216,7 +4216,7 @@ void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
*/
void checkLossOfPrecision(final DiagnosticPosition pos, Type found, Type req) {
if (found.isNumeric() && req.isNumeric() && !types.isAssignable(found, req)) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.LOSSY_CONVERSIONS))
log.warning(LintCategory.LOSSY_CONVERSIONS,
pos, Warnings.PossibleLossOfPrecision(found, req));
@@ -4420,7 +4420,7 @@ void checkDefaultConstructor(ClassSymbol c, DiagnosticPosition pos) {
// Warning may be suppressed by
// annotations; check again for being
// enabled in the deferred context.
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.MISSING_EXPLICIT_CTOR))
log.warning(LintCategory.MISSING_EXPLICIT_CTOR,
pos, Warnings.MissingExplicitCtor(c, pkg, modle));
@@ -4755,7 +4755,7 @@ private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inP
void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
if (msym.kind != MDL) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.MODULE))
log.warning(LintCategory.MODULE, pos, Warnings.ModuleNotFound(msym));
});
@@ -4765,7 +4765,7 @@ void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
if (packge.members().isEmpty() &&
((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (lint.isEnabled(LintCategory.OPENS))
log.warning(pos, Warnings.PackageEmptyOrNotFound(packge));
});
@@ -4774,7 +4774,7 @@ void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol pack
void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective rd) {
if ((rd.module.flags() & Flags.AUTOMATIC_MODULE) != 0) {
- deferredLintHandler.report(() -> {
+ deferredLintHandler.report(_l -> {
if (rd.isTransitive() && lint.isEnabled(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC)) {
log.warning(pos, Warnings.RequiresTransitiveAutomatic);
} else if (lint.isEnabled(LintCategory.REQUIRES_AUTOMATIC)) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
index eda2772fb75..da008bc4b53 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
@@ -470,7 +470,8 @@ public void visitPackageDef(JCPackageDecl tree) {
protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
if (swtch.hasTag(SWITCH_EXPRESSION)) {
- JCYield brk = make.at(Position.NOPOS).Yield(null);
+ JCYield brk = make.at(Position.NOPOS).Yield(make.Erroneous()
+ .setType(swtch.type));
brk.target = swtch;
scan(brk);
} else {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
index d716e9252d6..ef521f182f6 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -347,7 +347,7 @@ private void resolveImports(JCCompilationUnit tree, Env env) {
ImportFilter prevStaticImportFilter = staticImportFilter;
ImportFilter prevTypeImportFilter = typeImportFilter;
- DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
+ DiagnosticPosition prevLintPos = deferredLintHandler.immediate(lint);
Lint prevLint = chk.setLint(lint);
Env prevEnv = this.env;
try {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
index 88de2333069..403cb30921a 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
@@ -34,6 +34,8 @@
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
+import com.sun.tools.javac.tree.EndPosTable;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.*;
@@ -1207,6 +1209,8 @@ protected static class BasicComment extends PositionTrackingReader implements Co
*/
CommentStyle cs;
+ DiagnosticPosition pos;
+
/**
* true if comment contains @deprecated at beginning of a line.
*/
@@ -1228,6 +1232,12 @@ protected static class BasicComment extends PositionTrackingReader implements Co
protected BasicComment(CommentStyle cs, UnicodeReader reader, int pos, int endPos) {
super(reader, pos, endPos);
this.cs = cs;
+ this.pos = new SimpleDiagnosticPosition(pos) {
+ @Override
+ public int getEndPosition(EndPosTable endPosTable) {
+ return endPos;
+ }
+ };
}
/**
@@ -1239,6 +1249,10 @@ public String getText() {
return null;
}
+ public DiagnosticPosition getPos() {
+ return pos;
+ }
+
/**
* Return buffer position in original buffer mapped from buffer position in comment.
*
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
index dd4516fe7e7..ea12e676086 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -115,6 +115,12 @@ public class JavacParser implements Parser {
/** End position mappings container */
protected final AbstractEndPosTable endPosTable;
+ /** A map associating "other nearby documentation comments"
+ * with the preferred documentation comment for a declaration. */
+ protected Map> danglingComments = new HashMap<>();
+ /** Handler for deferred diagnostics. */
+ protected final DeferredLintHandler deferredLintHandler;
+
// Because of javac's limited lookahead, some contexts are ambiguous in
// the presence of type annotations even though they are not ambiguous
// in the absence of type annotations. Consider this code:
@@ -185,6 +191,7 @@ protected JavacParser(ParserFactory fac,
this.names = fac.names;
this.source = fac.source;
this.preview = fac.preview;
+ this.deferredLintHandler = fac.deferredLintHandler;
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
this.keepDocComments = keepDocComments;
this.parseModuleInfo = parseModuleInfo;
@@ -211,6 +218,7 @@ protected JavacParser(JavacParser parser,
this.names = parser.names;
this.source = parser.source;
this.preview = parser.preview;
+ this.deferredLintHandler = parser.deferredLintHandler;
this.allowStringFolding = parser.allowStringFolding;
this.keepDocComments = parser.keepDocComments;
this.parseModuleInfo = false;
@@ -562,16 +570,119 @@ protected void checkNoMods(int pos, long mods) {
*/
private final DocCommentTable docComments;
+ /** Record nearby documentation comments against the
+ * primary documentation comment for a declaration.
+ *
+ * Dangling documentation comments are handled as follows.
+ * 1. {@code Scanner} adds all doc comments to a queue of
+ * recent doc comments. The queue is flushed whenever
+ * it is known that the recent doc comments should be
+ * ignored and should not cause any warnings.
+ * 2. The primary documentation comment is the one obtained
+ * from the first token of any declaration.
+ * (using {@code token.getDocComment()}.
+ * 3. At the end of the "signature" of the declaration
+ * (that is, before any initialization or body for the
+ * declaration) any other "recent" comments are saved
+ * in a map using the primary comment as a key,
+ * using this method, {@code saveDanglingComments}.
+ * 4. When the tree node for the declaration is finally
+ * available, and the primary comment, if any,
+ * is "attached", (in {@link #attach}) any related
+ * dangling comments are also attached to the tree node
+ * by registering them using the {@link #deferredLintHandler}.
+ * 5. (Later) Warnings may be generated for the dangling
+ * comments, subject to the {@code -Xlint} and
+ * {@code @SuppressWarnings}.
+ *
+ * @param dc the primary documentation comment
+ */
+ private void saveDanglingDocComments(Comment dc) {
+ var recentComments = S.getDocComments();
+
+ switch (recentComments.size()) {
+ case 0:
+ // no recent comments
+ return;
+
+ case 1:
+ if (recentComments.peek() == dc) {
+ // no other recent comments
+ recentComments.remove();
+ return;
+ }
+ }
+
+ var lb = new ListBuffer();
+ while (!recentComments.isEmpty()) {
+ var c = recentComments.remove();
+ if (c != dc) {
+ lb.add(c);
+ }
+ }
+ danglingComments.put(dc, lb.toList());
+ }
+
/** Make an entry into docComments hashtable,
* provided flag keepDocComments is set and given doc comment is non-null.
+ * If there are any related "dangling comments", register
+ * diagnostics to be handled later, when @SuppressWarnings
+ * can be taken into account.
+ *
* @param tree The tree to be used as index in the hashtable
* @param dc The doc comment to associate with the tree, or null.
*/
protected void attach(JCTree tree, Comment dc) {
if (keepDocComments && dc != null) {
-// System.out.println("doc comment = ");System.out.println(dc);//DEBUG
docComments.putComment(tree, dc);
}
+ reportDanglingComments(tree, dc);
+ }
+
+ /** Reports all dangling comments associated with the
+ * primary comment for a declaration against the position
+ * of the tree node for a declaration.
+ *
+ * @param tree the tree node for the declaration
+ * @param dc the primary comment for the declaration
+ */
+ void reportDanglingComments(JCTree tree, Comment dc) {
+ var list = danglingComments.remove(dc);
+ if (list != null) {
+ var prevPos = deferredLintHandler.setPos(tree);
+ try {
+ list.forEach(this::reportDanglingDocComment);
+ } finally {
+ deferredLintHandler.setPos(prevPos);
+ }
+ }
+ }
+
+ /**
+ * Reports an individual dangling comment using the {@link #deferredLintHandler}.
+ * The comment may or not may generate an actual diagnostic, depending on
+ * the settings for {@code -Xlint} and/or {@code @SuppressWarnings}.
+ *
+ * @param c the comment
+ */
+ void reportDanglingDocComment(Comment c) {
+ var pos = c.getPos();
+ if (pos != null) {
+ deferredLintHandler.report(lint -> {
+ if (lint.isEnabled(Lint.LintCategory.DANGLING_DOC_COMMENTS)) {
+ log.warning(Lint.LintCategory.DANGLING_DOC_COMMENTS,
+ pos, Warnings.DanglingDocComment);
+ }
+ });
+ }
+ }
+
+ /**
+ * Ignores any recent documentation comments found by the scanner,
+ * such as those that cannot be associated with a nearby declaration.
+ */
+ private void ignoreDanglingComments() {
+ S.getDocComments().clear();
}
/* -------- source positions ------- */
@@ -2645,6 +2756,7 @@ JCNewClass classCreatorRest(int newpos,
List args = arguments();
JCClassDecl body = null;
if (token.kind == LBRACE) {
+ ignoreDanglingComments(); // ignore any comments from before the '{'
int pos = token.pos;
List defs = classInterfaceOrRecordBody(names.empty, false, false);
JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
@@ -2697,6 +2809,7 @@ JCExpression parExpression() {
*/
JCBlock block(int pos, long flags) {
accept(LBRACE);
+ ignoreDanglingComments(); // ignore any comments from before the '{'
List stats = blockStatements();
JCBlock t = F.at(pos).Block(flags, stats);
while (token.kind == CASE || token.kind == DEFAULT) {
@@ -2728,6 +2841,7 @@ List blockStatements() {
ListBuffer stats = new ListBuffer<>();
while (true) {
List stat = blockStatement();
+ ignoreDanglingComments(); // ignore comments not consumed by the statement
if (stat.isEmpty()) {
return stats.toList();
} else {
@@ -2799,7 +2913,7 @@ List blockStatement() {
return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
} else {
JCExpression t = parseType(true);
- return localVariableDeclarations(mods, t);
+ return localVariableDeclarations(mods, t, dc);
}
}
case ABSTRACT: case STRICTFP: {
@@ -2890,8 +3004,8 @@ List blockStatement() {
dc = token.docComment();
return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
}
+ dc = token.docComment();
if (isRecordStart() && allowRecords) {
- dc = token.docComment();
return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
} else {
Token prevToken = token;
@@ -2904,7 +3018,7 @@ List blockStatement() {
pos = token.pos;
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
F.at(pos);
- return localVariableDeclarations(mods, t);
+ return localVariableDeclarations(mods, t, dc);
} else {
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
t = checkExprStat(t);
@@ -2915,7 +3029,11 @@ List blockStatement() {
}
}
//where
- private List localVariableDeclarations(JCModifiers mods, JCExpression type) {
+ private List localVariableDeclarations(JCModifiers mods, JCExpression type, Comment dc) {
+ if (dc != null) {
+ // ignore a well-placed doc comment, but save any misplaced ones
+ saveDanglingDocComments(dc);
+ }
ListBuffer stats =
variableDeclarators(mods, type, new ListBuffer<>(), true);
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
@@ -2943,6 +3061,7 @@ private List