Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into maven-infra-plugi…
Browse files Browse the repository at this point in the history
…ns-version-bump
  • Loading branch information
saudet committed Jan 29, 2024
2 parents d2003a0 + 9012a1f commit 1cf8a29
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 203 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@

### January 29, 2024 version 1.5.10
* Move native `Loader` methods to `Helper` class to avoid deadlocks ([issue #737](https://github.com/bytedeco/javacpp/issues/737))
* Fix `Parser` failing to pick up `Info` for constructors with template arguments ([pull #739](https://github.com/bytedeco/javacpp/pull/739))
* Fix `MoveAdapter` and `UniquePtrAdapter` causing double free on function calls ([pull #738](https://github.com/bytedeco/javacpp/pull/738))
* Fix `Parser` handling of `template` specialization and their `friend` declarations ([pull #733](https://github.com/bytedeco/javacpp/pull/733))
* Improve `Parser` capabilities for `operator` and function templates ([pull #732](https://github.com/bytedeco/javacpp/pull/732))
* Fix `Parser` failing on nested initializer lists and on attributes found inside `enum` declarations
* Fix `Parser` for basic containers like `std::optional<std::pair<int,int> >` ([issue #718](https://github.com/bytedeco/javacpp/issues/718))
* Add support for `std::basic_string` basic container ([issue bytedeco/javacpp-presets#1311](https://github.com/bytedeco/javacpp-presets/issues/1311))
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,27 @@ We can also have everything downloaded and installed automatically with:
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.9</version>
<version>1.5.10</version>
</dependency>
```

* Gradle (inside the `build.gradle` file)
```groovy
dependencies {
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.9'
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.10'
}
```

* Leiningen (inside the `project.clj` file)
```clojure
:dependencies [
[org.bytedeco/javacpp "1.5.9"]
[org.bytedeco/javacpp "1.5.10"]
]
```

* sbt (inside the `build.sbt` file)
```scala
libraryDependencies += "org.bytedeco" % "javacpp" % "1.5.9"
libraryDependencies += "org.bytedeco" % "javacpp" % "1.5.10"
```

Another option available to Gradle users is [Gradle JavaCPP](https://github.com/bytedeco/gradle-javacpp), and similarly for Scala users there is [SBT-JavaCPP](https://github.com/bytedeco/sbt-javacpp).
Expand Down
2 changes: 1 addition & 1 deletion platform/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp-platform</artifactId>
<version>1.5.10-SNAPSHOT</version>
<version>1.5.11-SNAPSHOT</version>

<name>JavaCPP Platform</name>
<description>The missing bridge between Java and native C++</description>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.10-SNAPSHOT</version>
<version>1.5.11-SNAPSHOT</version>

<name>JavaCPP</name>
<description>The missing bridge between Java and native C++</description>
Expand Down
96 changes: 62 additions & 34 deletions src/main/java/org/bytedeco/javacpp/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -1968,16 +1968,6 @@ public static String createLibraryLink(String filename, ClassProperties properti
static WeakHashMap<Class<? extends Pointer>,HashMap<String,Integer>> memberOffsets =
new WeakHashMap<Class<? extends Pointer>,HashMap<String,Integer>>();

static {
try {
Loader.load();
} catch (Throwable t) {
if (logger.isDebugEnabled()) {
logger.debug("Could not load Loader: " + t);
}
}
}

/**
* Called by native libraries to put {@code offsetof()} and {@code sizeof()} values in {@link #memberOffsets}.
* Tries to load the Class object for typeName using the {@link ClassLoader} of the Loader.
Expand Down Expand Up @@ -2044,37 +2034,75 @@ public static int sizeof(Class<? extends Pointer> type) {
return offsetof(type, "sizeof");
}

public static class Helper {
static {
try {
Loader.load();
} catch (Throwable t) {
if (logger.isDebugEnabled()) {
logger.debug("Could not load Loader.Helper: " + t);
}
}
}

/** Returns the number of processors configured according to the operating system, or 0 if unknown.
* This value can be greater than {@link Runtime#availableProcessors()} and {@link #totalCores()}. */
@Name("JavaCPP_totalProcessors") public static native int totalProcessors();

/** Returns the number of CPU cores usable according to the operating system, or 0 if unknown.
* For SMT-capable systems, this value may be less than {@link #totalProcessors()}. */
@Name("JavaCPP_totalCores") public static native int totalCores();

/** Returns the number of CPU chips installed according to the operating system, or 0 if unknown.
* For multi-core processors, this value may be less than {@link #totalCores()}. */
@Name("JavaCPP_totalChips") public static native int totalChips();

/** Returns the address found under the given name in the "dynamic symbol tables" (Linux, Mac OS X, etc)
* or the "export tables" (Windows) of all libraries loaded, or null if not found. */
@Name("JavaCPP_addressof") public static native Pointer addressof(String symbol);

/** Loads all symbols from a library globally, that is {@code dlopen(filename, RTLD_LAZY | RTLD_GLOBAL)},
* or simply by default with {@code LoadLibrary(filename)} on Windows. If the library name passed to
* one of the other load functions in this class ends with "!", this function will get called on them. */
@Name("JavaCPP_loadGlobal") @Raw(withEnv = true) public static native void loadGlobal(String filename);

/** Returns the JavaVM JNI object, as required by some APIs for initialization. */
@Name("JavaCPP_getJavaVM") public static native @Cast("JavaVM*") Pointer getJavaVM();

/** Returns a JNI global reference stored in a Pointer for the given Object. */
@Name("JavaCPP_newGlobalRef") public static native @Cast("jobject") Pointer newGlobalRef(@Raw(withEnv = true) Object object);

/** Returns an Object from the JNI global reference stored in the Pointer. */
@Name("JavaCPP_accessGlobalRef") @Raw(withEnv = true) public static native Object accessGlobalRef(@Cast("jobject") Pointer globalRef);

/** Deletes the JNI global reference stored in the Pointer. */
@Name("JavaCPP_deleteGlobalRef") @Raw(withEnv = true) public static native void deleteGlobalRef(@Cast("jobject") Pointer globalRef);
}

/** Returns the number of processors configured according to the operating system, or 0 if unknown.
* This value can be greater than {@link Runtime#availableProcessors()} and {@link #totalCores()}. */
@Name("JavaCPP_totalProcessors") public static native int totalProcessors();
/** Returns {@link Helper#totalProcessors()}. */
public static int totalProcessors() { return Helper.totalProcessors(); }

/** Returns the number of CPU cores usable according to the operating system, or 0 if unknown.
* For SMT-capable systems, this value may be less than {@link #totalProcessors()}. */
@Name("JavaCPP_totalCores") public static native int totalCores();
/** Returns {@link Helper#totalCores()}. */
public static int totalCores() { return Helper.totalCores(); }

/** Returns the number of CPU chips installed according to the operating system, or 0 if unknown.
* For multi-core processors, this value may be less than {@link #totalCores()}. */
@Name("JavaCPP_totalChips") public static native int totalChips();
/** Returns {@link Helper#totalChips()}. */
public static int totalChips() { return Helper.totalChips(); }

/** Returns the address found under the given name in the "dynamic symbol tables" (Linux, Mac OS X, etc)
* or the "export tables" (Windows) of all libraries loaded, or null if not found. */
@Name("JavaCPP_addressof") public static native Pointer addressof(String symbol);
/** Returns {@link Helper#addressof(String)}. */
public static Pointer addressof(String symbol) { return Helper.addressof(symbol); }

/** Loads all symbols from a library globally, that is {@code dlopen(filename, RTLD_LAZY | RTLD_GLOBAL)},
* or simply by default with {@code LoadLibrary(filename)} on Windows. If the library name passed to
* one of the other load functions in this class ends with "!", this function will get called on them. */
@Name("JavaCPP_loadGlobal") @Raw(withEnv = true) public static native void loadGlobal(String filename);
/** Calls {@link Helper#loadGlobal(String)}. */
public static void loadGlobal(String filename) { Helper.loadGlobal(filename); }

/** Returns the JavaVM JNI object, as required by some APIs for initialization. */
@Name("JavaCPP_getJavaVM") public static native @Cast("JavaVM*") Pointer getJavaVM();
/** Returns {@link Helper#getJavaVM()}. */
public static Pointer getJavaVM() { return Helper.getJavaVM(); }

/** Returns a JNI global reference stored in a Pointer for the given Object. */
@Name("JavaCPP_newGlobalRef") public static native @Cast("jobject") Pointer newGlobalRef(@Raw(withEnv = true) Object object);
/** Returns {@link Helper#newGlobalRef(Object)}. */
public static Pointer newGlobalRef(Object object) { return Helper.newGlobalRef(object); }

/** Returns an Object from the JNI global reference stored in the Pointer. */
@Name("JavaCPP_accessGlobalRef") @Raw(withEnv = true) public static native Object accessGlobalRef(@Cast("jobject") Pointer globalRef);
/** Returns {@link Helper#accessGlobalRef(Pointer)}. */
public static Object accessGlobalRef(Pointer globalRef) { return Helper.accessGlobalRef(globalRef); }

/** Deletes the JNI global reference stored in the Pointer. */
@Name("JavaCPP_deleteGlobalRef") @Raw(withEnv = true) public static native void deleteGlobalRef(@Cast("jobject") Pointer globalRef);
/** Calls {@link Helper#deleteGlobalRef(Pointer)}. */
public static void deleteGlobalRef(Pointer globalRef) { Helper.deleteGlobalRef(globalRef); }
}
32 changes: 17 additions & 15 deletions src/main/java/org/bytedeco/javacpp/tools/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,26 @@ String[] qualify(String cppName, String parameters) {
name = name.substring(0, name.length() - parameters.length());
}
TemplateMap map = templateMap;
while (map != null) {
String name2 = map.getName();
if (parameters != null && name2 != null && name2.endsWith(parameters)) {
name2 = name2.substring(0, name2.length() - parameters.length());
}
if (name.equals(name2)) {
String args = "<", separator = "";
for (Type t : map.values()) {
// assume that missing arguments have default values
if (t != null) {
args += separator + t.cppName;
separator = ",";
if (!name.endsWith(">")) {
while (map != null) {
String name2 = map.getName();
if (parameters != null && name2 != null && name2.endsWith(parameters)) {
name2 = name2.substring(0, name2.length() - parameters.length());
}
if (name.equals(name2)) {
String args = "<", separator = "";
for (Type t : map.values()) {
// assume that missing arguments have default values
if (t != null) {
args += separator + t.cppName;
separator = ",";
}
}
names.add(name + args + (args.endsWith(">") ? " >" : ">") + (parameters != null ? parameters : ""));
break;
}
names.add(name + args + (args.endsWith(">") ? " >" : ">") + (parameters != null ? parameters : ""));
break;
map = map.parent;
}
map = map.parent;
}
names.add(name);

Expand Down
14 changes: 8 additions & 6 deletions src/main/java/org/bytedeco/javacpp/tools/DeclarationList.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,23 @@ public boolean add(Declaration decl, String fullName) {
boolean add = true;
if (templateMap != null && templateMap.empty() && !decl.custom && (decl.type != null || decl.declarator != null)) {
// method templates cannot be declared in Java, but make sure to make their
// info available on request (when Info.javaNames is set) to be able to create instances
// info available on request (when Info.javaNames or Info.define is set) to be able to create instances
// decl.custom is true when info has a javaText and define is false. This allows to apply a javaText
// to a template without instantiating it. define forces instantiation.
if (infoIterator == null) {
Type type = templateMap.type = decl.type;
Declarator dcl = templateMap.declarator = decl.declarator;
for (String name : new String[] {fullName, dcl != null ? dcl.cppName : type.cppName}) {
for (String name : new String[] {fullName, dcl != null ? (dcl.type.constructor ? Parser.constructorName(dcl.cppName) : dcl.cppName) : type.cppName}) {
if (name == null) {
continue;
}
List<Info> infoList = infoMap.get(name);
boolean hasJavaName = false;
boolean hasJavaNameOrDefine = false;
for (Info info : infoList) {
hasJavaName |= info.javaNames != null && info.javaNames.length > 0;
hasJavaNameOrDefine |= info.javaNames != null && info.javaNames.length > 0 || info.define;
}
if (!decl.function || hasJavaName) {
infoIterator = infoList.size() > 0 ? infoList.listIterator() : null;
if (!decl.function || hasJavaNameOrDefine) {
infoIterator = infoList.size() > 0 ? new ArrayList<>(infoList).listIterator() : null;
break;
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/org/bytedeco/javacpp/tools/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ static enum LongEnum { LONG; long value; }
static final String JNI_VERSION = "JNI_VERSION_1_6";
static final List<Class> baseClasses = Arrays.asList(new Class[] {
Loader.class,
Loader.Helper.class,
Pointer.class,
//FunctionPointer.class,
BytePointer.class,
Expand Down Expand Up @@ -1408,7 +1409,7 @@ boolean classes(boolean handleExceptions, boolean defineAdapters, boolean conver
out.println(" return (typename UNIQUE_PTR_NAMESPACE::remove_const<T>::type*)ptr;");
out.println(" }");
out.println(" operator U&() const { return uniquePtr; }");
out.println(" operator U&&() { return UNIQUE_PTR_NAMESPACE::move(uniquePtr); }");
out.println(" operator U&&() { owner = NULL; return UNIQUE_PTR_NAMESPACE::move(uniquePtr); }");
out.println(" operator U*() { return &uniquePtr; }");
out.println(" T* ptr;");
out.println(" size_t size;");
Expand Down Expand Up @@ -1437,7 +1438,7 @@ boolean classes(boolean handleExceptions, boolean defineAdapters, boolean conver
out.println(" return ptr;");
out.println(" }");
out.println(" operator const T*() { return ptr; }");
out.println(" operator T&&() { return MOVE_NAMESPACE::move(movedPtr); }");
out.println(" operator T&&() { owner = NULL; return MOVE_NAMESPACE::move(movedPtr); }");
out.println(" T* ptr;");
out.println(" size_t size;");
out.println(" void* owner;");
Expand Down Expand Up @@ -2065,6 +2066,7 @@ boolean methods(Class<?> cls) {
Set<String> memberList = members.get(cls);
if (!cls.isAnnotationPresent(Opaque.class) && cls != Loader.class
&& !FunctionPointer.class.isAssignableFrom(cls)
&& cls.getEnclosingClass() != Loader.class
&& cls.getEnclosingClass() != Pointer.class) {
if (memberList == null) {
members.put(cls, memberList = new LinkedHashSet<String>());
Expand Down
53 changes: 15 additions & 38 deletions src/main/java/org/bytedeco/javacpp/tools/InfoMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public class InfoMap extends HashMap<String,List<Info>> {
"std::function", "std::basic_string"))
.put(new Info("basic/types").cppTypes("signed", "unsigned", "char", "short", "int", "long", "bool", "float", "double",
"__int8", "__int16", "__int32", "__int64", "_Bool", "_Complex", "_Imaginary", "complex", "imaginary"))
.put(new Info("deprecated").annotations("@Deprecated"))
.put(new Info("noexcept").annotations("@NoException(true)"))

.put(new Info("__COUNTER__").cppText("#define __COUNTER__ 0"))
Expand Down Expand Up @@ -185,6 +184,21 @@ String normalize(String name, boolean unconst, boolean untemplate) {
if (name == null || name.length() == 0 || name.startsWith("basic/")) {
return name;
}
if (untemplate) {
// Remove template arguments in the last NS component only, and not in parameters, if any
List<String> comps = Templates.splitNamespace(name, true);
int paramsIdx = comps.size() - 1;
String lastComp = comps.get(paramsIdx - 1);
comps.set(paramsIdx - 1, Templates.strip(lastComp));
name = comps.get(0);
for (int i = 1; i < paramsIdx; i++) {
name += "::" + comps.get(i);
}
name += comps.get(paramsIdx);
if (name.isEmpty()) {
return name;
}
}
boolean foundConst = false, simpleType = true;
String prefix = null;
Token[] tokens = new Tokenizer(name, null, 0).tokenize();
Expand Down Expand Up @@ -216,43 +230,6 @@ String normalize(String name, boolean unconst, boolean untemplate) {
for (int i = 1; i < n; i++) {
name += " " + tokens[i].value;
}
} else if (untemplate) {
int count = 0, lastColon = -1, template = -1, parameters = n;
for (int i = 0; i < n; i++) {
if (tokens[i].match('<')) {
count++;
} else if (tokens[i].match('>')) {
count--;
}
if (count == 0 && tokens[i].match("::")) {
lastColon = i;
} else if (count == 0 && tokens[i].match('(')) {
parameters = i;
break;
}
}
for (int i = lastColon + 1; i < parameters; i++) {
if (tokens[i].match('<')) {
if (count == 0) {
template = i;
}
count++;
} else if (tokens[i].match('>')) {
count--;
if (count == 0 && i + 1 != parameters) {
template = -1;
}
}
}
if (template >= 0) {
name = foundConst ? "const " : "";
for (int i = 0; i < template; i++) {
name += tokens[i];
}
for (int i = parameters; i < n; i++) {
name += tokens[i].spacing + tokens[i];
}
}
}
if (unconst && foundConst) {
name = name.substring(name.indexOf("const") + 5);
Expand Down
Loading

0 comments on commit 1cf8a29

Please sign in to comment.