Skip to content

Commit 886f7f1

Browse files
committed
SimpleDateFormat, NativeLibrary, native transpiler fix
adds the return type for public static native methods. Removes SimpleDateFormat dependencies for simple date generation in JavaScript, such as "MM/DD/YY"
1 parent 87ae845 commit 886f7f1

File tree

23 files changed

+7575
-1919
lines changed

23 files changed

+7575
-1919
lines changed
7.29 KB
Binary file not shown.
45 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20250228085852
1+
20250310145920
7.29 KB
Binary file not shown.
45 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20250224211151
1+
20250310145920

sources/net.sf.j2s.core/src/j2s/CorePlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ public class CorePlugin extends Plugin {
2626
* the actual "x.y.z" version is specified in plugin.xml.
2727
*
2828
*/
29-
public static String VERSION = "5.0.1-v5";
29+
public static String VERSION = "5.0.1-v6";
3030

3131
// if you change the x.x.x number, be sure to also indicate that in
3232
// j2sApplet.js and also (Bob only) update.bat, update-clean.bat
3333

34+
// BH 2025.03.05 -- 5.0.1-v6 adds native interface methods for WASM
3435
// BH 2025.02.22 -- 5.0.1-v5 fixes Iterable<IAtom> AtomIterator::new missing [this,null] in generator
3536
// BH 2024.07.14 -- 5.0.1-v4 fixes numerical array initializer using characters ['a','b',...]
3637
// BH 2024.02.22 -- 5.0.1-v3 fixes long extension issue causing MutableBitInteger to miscalculate subtraction(no change in version #)

sources/net.sf.j2s.core/src/j2s/swingjs/Java2ScriptVisitor.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
// TODO: superclass inheritance for JAXB XmlAccessorType
3232
// TODO: Transpiler bug allows static String name, but JavaScript function().name is read-only and will be "clazz"
3333

34+
//BH 2025.03.05 -- 5.0.1-v6 adds native interface methods for WASM
3435
//BH 2025.02.22 -- 5.0.1-v5 fixes Iterable<IAtom> AtomIterator::new missing [this,null] in generator
3536
//BH 2024.07.14 -- 5.0.1-v4 fixes numerical array initializer using characters ['a','b',...], but not new int[] { "test".charAt(3) }
3637
//BH 2024.02.22 -- 5.0.1-v3 fixes long extension issue causing MutableBitInteger to miscalculate subtraction(no change in version #)
@@ -1415,10 +1416,15 @@ private void processMethodDeclaration(MethodDeclaration mnode, IMethodBinding mB
14151416
body.accept(this);
14161417
}
14171418
meth_current = prevMethod;
1418-
if (isStatic || isConstructor)
1419+
if (isStatic || isConstructor) {
14191420
buffer.append(", ").append(isNative ? 2 : 1);
1420-
else if (isPrivate)
1421+
if (isNative) {
1422+
ITypeBinding ret = mBinding.getReturnType();
1423+
buffer.append(", \""+getUnreplacedJavaClassNameQualified(ret)+"\"");
1424+
}
1425+
} else if (isPrivate) {
14211426
buffer.append(", " + getPrivateVar(mClass, false));
1427+
}
14221428
buffer.append(");\n");
14231429

14241430
}
6.67 KB
Binary file not shown.
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/*
2+
* The contents of this file is dual-licensed under 2
3+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
4+
* Apache License 2.0. (starting with JNA version 4.0.0).
5+
*
6+
* You can freely decide which license you want to apply to
7+
* the project.
8+
*
9+
* You may obtain a copy of the LGPL License at:
10+
*
11+
* http://www.gnu.org/licenses/licenses.html
12+
*
13+
* A copy is also included in the downloadable source code package
14+
* containing JNA, in file "LGPL2.1".
15+
*
16+
* You may obtain a copy of the Apache License at:
17+
*
18+
* http://www.apache.org/licenses/
19+
*
20+
* A copy is also included in the downloadable source code package
21+
* containing JNA, in file "AL2.0".
22+
*/
23+
package com.sun.jna;
24+
25+
//import com.sun.jna.internal.ReflectionUtils;
26+
//import java.lang.reflect.InvocationHandler;
27+
//import java.lang.reflect.Method;
28+
//import java.lang.reflect.Proxy;
29+
//import java.util.HashMap;
30+
//import java.util.Map;
31+
//import java.util.WeakHashMap;
32+
33+
/** Derive from this interface for all native library definitions.
34+
*
35+
* Define an instance of your library like this:
36+
* <pre><code>
37+
* MyNativeLibrary INSTANCE = (MyNativeLibrary)
38+
* Native.load("mylib", MyNativeLibrary.class);
39+
* </code></pre>
40+
* <p>
41+
* By convention, method names are identical to the native names, although you
42+
* can map java names to different native names by providing a
43+
* {@link FunctionMapper} as a value for key {@link #OPTION_FUNCTION_MAPPER}
44+
* in the options map passed to the
45+
* {@link Native#load(String, Class, Map)} call.
46+
* <p>
47+
* Although the names for structures and structure fields may be chosen
48+
* arbitrarily, they should correspond as closely as possible to the native
49+
* definitions. The same is true for parameter names.
50+
* <p>
51+
* This interface supports multiple, concurrent invocations of any library
52+
* methods on the Java side. Check your library documentation for its
53+
* multi-threading requirements on the native side. If a library is not safe
54+
* for simultaneous multi-threaded access, consider using
55+
* {@link Native#synchronizedLibrary} to prevent simultaneous multi-threaded
56+
* access to the native code.
57+
* <p>
58+
* <b>Optional fields</b><br>
59+
* Interface options will be automatically propagated to structures defined
60+
* within the library provided a call to
61+
* {@link Native#load(String,Class,Map)} is made prior to instantiating
62+
* any of those structures. One common way of ensuring this is to declare
63+
* an <b>INSTANCE</b> field in the interface which holds the
64+
* <code>load</code> result.
65+
* <p>
66+
* <b>OPTIONS</b> (an instance of {@link Map}),
67+
* <b>TYPE_MAPPER</b> (an instance of {@link TypeMapper}),
68+
* <b>STRUCTURE_ALIGNMENT</b> (one of the alignment types defined in
69+
* {@link Structure}), and <b>STRING_ENCODING</b> (a {@link String}) may also
70+
* be defined. If no instance of the interface has been instantiated, these
71+
* fields will be used to determine customization settings for structures and
72+
* methods defined within the interface.
73+
* <p>
74+
*
75+
* @author Todd Fast, todd.fast@sun.com
76+
* @author Timothy Wall, twalljava@dev.java.net
77+
*/
78+
public interface Library {
79+
// /** Option key for a {@link TypeMapper} for the library. */
80+
// String OPTION_TYPE_MAPPER = "type-mapper";
81+
// /** Option key for a {@link FunctionMapper} for the library. */
82+
// String OPTION_FUNCTION_MAPPER = "function-mapper";
83+
// /** Option key for an {@link InvocationMapper} for the library. */
84+
// String OPTION_INVOCATION_MAPPER = "invocation-mapper";
85+
// /** Option key for structure alignment type ({@link Integer}), which should
86+
// * be one of the predefined alignment types in {@link Structure}.
87+
// */
88+
// String OPTION_STRUCTURE_ALIGNMENT = "structure-alignment";
89+
// /** <p>Option key for per-library String encoding. This affects conversions
90+
// * between Java unicode and native (<code>const char*</code>) strings (as
91+
// * arguments or Structure fields).
92+
// * </p>
93+
// * Defaults to {@link Native#getDefaultStringEncoding()}.
94+
// */
95+
// String OPTION_STRING_ENCODING = "string-encoding";
96+
// /** Option key for a boolean flag to allow any Java class instance as a
97+
// parameter. If no type mapper is found, the object is passed as a
98+
// pointer.
99+
// <em>NOTE:</em> This is for use with raw JNI interactions via the
100+
// JNIEnv data structure.
101+
// */
102+
// String OPTION_ALLOW_OBJECTS = "allow-objects";
103+
// /** Calling convention for the entire library. */
104+
// String OPTION_CALLING_CONVENTION = "calling-convention";
105+
// /** Flags to use when opening the native library (see {@link Native#open(String,int)}) */
106+
// String OPTION_OPEN_FLAGS = "open-flags";
107+
// /** <p>Class loader to use when searching for native libraries on the
108+
// * resource path (classpath). If not provided the current thread's
109+
// * context class loader is used.</p>
110+
// * If extracted from the resource path (i.e. bundled in a jar file), the
111+
// * loaded library's lifespan will mirror that of the class loader, which
112+
// * means you can use the same library in isolated contexts without
113+
// * conflict.
114+
// */
115+
// String OPTION_CLASSLOADER = "classloader";
116+
//
117+
// /**
118+
// * Supports a custom symbol provider for the NativeLibrary (see {@link SymbolProvider})
119+
// */
120+
// String OPTION_SYMBOL_PROVIDER = "symbol-provider";
121+
//
122+
// static class Handler implements InvocationHandler {
123+
//
124+
// static final Method OBJECT_TOSTRING;
125+
// static final Method OBJECT_HASHCODE;
126+
// static final Method OBJECT_EQUALS;
127+
//
128+
// static {
129+
// try {
130+
// OBJECT_TOSTRING = Object.class.getMethod("toString");
131+
// OBJECT_HASHCODE= Object.class.getMethod("hashCode");
132+
// OBJECT_EQUALS = Object.class.getMethod("equals", Object.class);
133+
// } catch (Exception e) {
134+
// throw new Error("Error retrieving Object.toString() method");
135+
// }
136+
// }
137+
//
138+
// /**
139+
// * FunctionInfo has to be immutable to to make the object visible
140+
// * to other threads fully initialized. This is a prerequisite for
141+
// * using the class in the double checked locking scenario of {@link Handler#invoke(Object, Method, Object[])}
142+
// */
143+
// private static final class FunctionInfo {
144+
// final InvocationHandler handler;
145+
// final Function function;
146+
// final boolean isVarArgs;
147+
// final Object methodHandle;
148+
// final Map<String, ?> options;
149+
// final Class<?>[] parameterTypes;
150+
//
151+
// FunctionInfo(Object mh) {
152+
// this.handler = null;
153+
// this.function = null;
154+
// this.isVarArgs = false;
155+
// this.options = null;
156+
// this.parameterTypes = null;
157+
// this.methodHandle = mh;
158+
// }
159+
//
160+
// FunctionInfo(InvocationHandler handler, Function function, Class<?>[] parameterTypes, boolean isVarArgs, Map<String, ?> options) {
161+
// this.handler = handler;
162+
// this.function = function;
163+
// this.isVarArgs = isVarArgs;
164+
// this.options = options;
165+
// this.parameterTypes = parameterTypes;
166+
// this.methodHandle = null;
167+
// }
168+
// }
169+
//
170+
// private final NativeLibrary nativeLibrary;
171+
// private final Class<?> interfaceClass;
172+
// // Library invocation options
173+
// private final Map<String, Object> options;
174+
// private final InvocationMapper invocationMapper;
175+
// private final Map<Method, FunctionInfo> functions = new WeakHashMap<>();
176+
// public Handler(String libname, Class<?> interfaceClass, Map<String, ?> options) {
177+
//
178+
// if (libname != null && "".equals(libname.trim())) {
179+
// throw new IllegalArgumentException("Invalid library name \"" + libname + "\"");
180+
// }
181+
//
182+
// if (!interfaceClass.isInterface()) {
183+
// throw new IllegalArgumentException(libname + " does not implement an interface: " + interfaceClass.getName());
184+
// }
185+
//
186+
// this.interfaceClass = interfaceClass;
187+
// this.options = new HashMap<>(options);
188+
// int callingConvention = AltCallingConvention.class.isAssignableFrom(interfaceClass)
189+
// ? Function.ALT_CONVENTION
190+
// : Function.C_CONVENTION;
191+
// if (this.options.get(OPTION_CALLING_CONVENTION) == null) {
192+
// this.options.put(OPTION_CALLING_CONVENTION, Integer.valueOf(callingConvention));
193+
// }
194+
// if (this.options.get(OPTION_CLASSLOADER) == null) {
195+
// this.options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader());
196+
// }
197+
// this.nativeLibrary = NativeLibrary.getInstance(libname, this.options);
198+
// invocationMapper = (InvocationMapper)this.options.get(OPTION_INVOCATION_MAPPER);
199+
// }
200+
//
201+
// public NativeLibrary getNativeLibrary() {
202+
// return nativeLibrary;
203+
// }
204+
//
205+
// public String getLibraryName() {
206+
// return nativeLibrary.getName();
207+
// }
208+
//
209+
// public Class<?> getInterfaceClass() {
210+
// return interfaceClass;
211+
// }
212+
//
213+
// @Override
214+
// public Object invoke(Object proxy, Method method, Object[] inArgs)
215+
// throws Throwable {
216+
//
217+
// // Intercept Object methods
218+
// if (OBJECT_TOSTRING.equals(method)) {
219+
// return "Proxy interface to " + nativeLibrary;
220+
// } else if (OBJECT_HASHCODE.equals(method)) {
221+
// return Integer.valueOf(hashCode());
222+
// } else if (OBJECT_EQUALS.equals(method)) {
223+
// Object o = inArgs[0];
224+
// if (o != null && Proxy.isProxyClass(o.getClass())) {
225+
// return Function.valueOf(Proxy.getInvocationHandler(o) == this);
226+
// }
227+
// return Boolean.FALSE;
228+
// }
229+
//
230+
// // Using the double-checked locking pattern to speed up function calls
231+
// FunctionInfo f = functions.get(method);
232+
// if(f == null) {
233+
// synchronized(functions) {
234+
// f = functions.get(method);
235+
// if (f == null) {
236+
// boolean isDefault = ReflectionUtils.isDefault(method);
237+
// if(! isDefault) {
238+
// boolean isVarArgs = Function.isVarArgs(method);
239+
// InvocationHandler handler = null;
240+
// if (invocationMapper != null) {
241+
// handler = invocationMapper.getInvocationHandler(nativeLibrary, method);
242+
// }
243+
// Function function = null;
244+
// Class<?>[] parameterTypes = null;
245+
// Map<String, Object> options = null;
246+
// if (handler == null) {
247+
// // Find the function to invoke
248+
// function = nativeLibrary.getFunction(method.getName(), method);
249+
// parameterTypes = method.getParameterTypes();
250+
// options = new HashMap<>(this.options);
251+
// options.put(Function.OPTION_INVOKING_METHOD, method);
252+
// }
253+
// f = new FunctionInfo(handler, function, parameterTypes, isVarArgs, options);
254+
// } else {
255+
// f = new FunctionInfo(ReflectionUtils.getMethodHandle(method));
256+
// }
257+
// functions.put(method, f);
258+
// }
259+
// }
260+
// }
261+
// if (f.methodHandle != null) {
262+
// return ReflectionUtils.invokeDefaultMethod(proxy, f.methodHandle, inArgs);
263+
// } else {
264+
// if (f.isVarArgs) {
265+
// inArgs = Function.concatenateVarArgs(inArgs);
266+
// }
267+
// if (f.handler != null) {
268+
// return f.handler.invoke(proxy, method, inArgs);
269+
// }
270+
// return f.function.invoke(method, f.parameterTypes, method.getReturnType(), inArgs, f.options);
271+
// }
272+
// }
273+
// }
274+
}

0 commit comments

Comments
 (0)