Skip to content

Commit 61c6112

Browse files
committed
Fix native runtime linking for file streams
1 parent 0ee75dc commit 61c6112

File tree

7 files changed

+120
-20
lines changed

7 files changed

+120
-20
lines changed

vm/ByteCodeTranslator/src/cn1_globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <stdio.h>
55
#include <stdlib.h>
6+
7+
#define CN1_GLOBALS_IMPLEMENTED 1
68
#include "cn1_class_method_index.h"
79
#include <pthread.h>
810
#include <setjmp.h>

vm/ByteCodeTranslator/src/cn1_globals.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "cn1_globals.h"
22
#include <assert.h>
3+
#include <unistd.h>
34
#include "java_lang_Class.h"
45
#include "java_lang_Object.h"
56
#include "java_lang_Boolean.h"
@@ -14,6 +15,10 @@
1415
#include "java_lang_Float.h"
1516
#include "java_lang_Runnable.h"
1617
#include "java_lang_System.h"
18+
19+
JAVA_BOOLEAN lowMemoryMode = JAVA_FALSE;
20+
int mallocWhileSuspended = 0;
21+
BOOL isAppSuspended = NO;
1722
#include "java_lang_ArrayIndexOutOfBoundsException.h"
1823
#if defined(__APPLE__) && defined(__OBJC__)
1924
#import <mach/mach.h>

vm/ByteCodeTranslator/src/com/codename1/tools/translator/ByteCodeTranslator.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ private static void handleCleanOutput(ByteCodeTranslator b, File[] sources, File
244244
copy(ByteCodeTranslator.class.getResourceAsStream("/xmlvm.h"), new FileOutputStream(xmlvm));
245245
File nativeMethods = new File(srcRoot, "nativeMethods.m");
246246
copy(ByteCodeTranslator.class.getResourceAsStream("/nativeMethods.m"), new FileOutputStream(nativeMethods));
247+
File cn1GlobalsM = new File(srcRoot, "cn1_globals.m");
248+
copy(ByteCodeTranslator.class.getResourceAsStream("/cn1_globals.m"), new FileOutputStream(cn1GlobalsM));
247249
File javaIoFileM = new File(srcRoot, "java_io_File.m");
248250
copy(ByteCodeTranslator.class.getResourceAsStream("/java_io_File.m"), new FileOutputStream(javaIoFileM));
249251
File javaIoFileStreamsM = new File(srcRoot, "java_io_FileStreams.m");

vm/ByteCodeTranslator/src/java_io_FileStreams.m

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static JAVA_LONG retainHandle(NSFileHandle* handle) {
2121
return (JAVA_LONG)(uintptr_t)handle;
2222
}
2323

24-
JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_OBJECT path) {
24+
JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT path) {
2525
if (path == JAVA_NULL) {
2626
return 0;
2727
}
@@ -33,7 +33,7 @@ JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ON
3333
return result;
3434
}
3535

36-
JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
36+
JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
3737
NSFileHandle* h = toHandle(handle);
3838
if (h == nil) {
3939
return -1;
@@ -48,7 +48,7 @@ JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODEN
4848
return count == 0 ? -1 : (JAVA_INT)count;
4949
}
5050

51-
JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle, JAVA_LONG n) {
51+
JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle, JAVA_LONG n) {
5252
NSFileHandle* h = toHandle(handle);
5353
if (h == nil) {
5454
return 0;
@@ -63,7 +63,7 @@ JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREA
6363
return (JAVA_LONG)(updated - current);
6464
}
6565

66-
JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
66+
JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
6767
NSFileHandle* h = toHandle(handle);
6868
if (h == nil) {
6969
return 0;
@@ -83,7 +83,7 @@ JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_
8383
return (JAVA_INT)diff;
8484
}
8585

86-
JAVA_VOID java_io_FileInputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
86+
JAVA_VOID java_io_FileInputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
8787
NSFileHandle* h = toHandle(handle);
8888
if (h == nil) {
8989
return;
@@ -161,7 +161,7 @@ static int toFd(JAVA_LONG handle) {
161161
return (int)handle;
162162
}
163163

164-
JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_OBJECT path) {
164+
JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT path) {
165165
if (path == JAVA_NULL) {
166166
return 0;
167167
}
@@ -173,7 +173,7 @@ JAVA_LONG java_io_FileInputStream_openImpl___java_lang_String_R_long(CODENAME_ON
173173
return (JAVA_LONG)fd;
174174
}
175175

176-
JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
176+
JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
177177
int fd = toFd(handle);
178178
if (fd < 0 || buffer == JAVA_NULL) {
179179
return -1;
@@ -185,7 +185,7 @@ JAVA_INT java_io_FileInputStream_readImpl___long_byte_1ARRAY_int_int_R_int(CODEN
185185
return (JAVA_INT)count;
186186
}
187187

188-
JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle, JAVA_LONG n) {
188+
JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle, JAVA_LONG n) {
189189
int fd = toFd(handle);
190190
if (fd < 0 || n <= 0) {
191191
return 0;
@@ -201,7 +201,7 @@ JAVA_LONG java_io_FileInputStream_skipImpl___long_long_R_long(CODENAME_ONE_THREA
201201
return (JAVA_LONG)(target - current);
202202
}
203203

204-
JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
204+
JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
205205
int fd = toFd(handle);
206206
if (fd < 0) {
207207
return 0;
@@ -225,14 +225,14 @@ JAVA_INT java_io_FileInputStream_availableImpl___long_R_int(CODENAME_ONE_THREAD_
225225
return (JAVA_INT)diff;
226226
}
227227

228-
JAVA_VOID java_io_FileInputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
228+
JAVA_VOID java_io_FileInputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
229229
int fd = toFd(handle);
230230
if (fd >= 0) {
231231
close(fd);
232232
}
233233
}
234234

235-
JAVA_LONG java_io_FileOutputStream_openImpl___java_lang_String_boolean_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_OBJECT path, JAVA_BOOLEAN append) {
235+
JAVA_LONG java_io_FileOutputStream_openImpl___java_lang_String_boolean_R_long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT path, JAVA_BOOLEAN append) {
236236
if (path == JAVA_NULL) {
237237
return 0;
238238
}
@@ -250,7 +250,7 @@ JAVA_LONG java_io_FileOutputStream_openImpl___java_lang_String_boolean_R_long(CO
250250
return (JAVA_LONG)fd;
251251
}
252252

253-
JAVA_VOID java_io_FileOutputStream_writeImpl___long_byte_1ARRAY_int_int(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
253+
JAVA_VOID java_io_FileOutputStream_writeImpl___long_byte_1ARRAY_int_int(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle, JAVA_OBJECT buffer, JAVA_INT off, JAVA_INT len) {
254254
int fd = toFd(handle);
255255
if (fd < 0 || buffer == JAVA_NULL || len <= 0) {
256256
return;
@@ -259,14 +259,14 @@ JAVA_VOID java_io_FileOutputStream_writeImpl___long_byte_1ARRAY_int_int(CODENAME
259259
(void)written;
260260
}
261261

262-
JAVA_VOID java_io_FileOutputStream_flushImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
262+
JAVA_VOID java_io_FileOutputStream_flushImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
263263
int fd = toFd(handle);
264264
if (fd >= 0) {
265265
fsync(fd);
266266
}
267267
}
268268

269-
JAVA_VOID java_io_FileOutputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, JAVA_LONG handle) {
269+
JAVA_VOID java_io_FileOutputStream_closeImpl___long(CODENAME_ONE_THREAD_STATE, JAVA_LONG handle) {
270270
int fd = toFd(handle);
271271
if (fd >= 0) {
272272
close(fd);

vm/ByteCodeTranslator/src/nativeMethods.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,7 @@ JAVA_OBJECT java_lang_String_format___java_lang_String_java_lang_Object_1ARRAY_R
18561856

18571857
// Additional Stubs for Linking
18581858

1859+
#if !defined(CN1_GLOBALS_IMPLEMENTED)
18591860
struct clazz class_array1__JAVA_BOOLEAN = {0};
18601861
struct clazz class_array1__JAVA_CHAR = {0};
18611862
struct clazz class_array1__JAVA_BYTE = {0};
@@ -1998,4 +1999,5 @@ void initConstantPool() {
19981999
pthread_key_t recursionKey;
19992000
int currentGcMarkValue = 0;
20002001

2001-
#endif
2002+
#endif /* !CN1_GLOBALS_IMPLEMENTED */
2003+
#endif /* __APPLE__ */

vm/tests/src/test/java/com/codename1/tools/translator/FileStreamsIntegrationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ private String fileStreamAppSource() {
131131
" if (filtered == null || filtered.length == 0) System.exit(1);\n" +
132132
" }\n" +
133133
" } catch (Exception e) {\n" +
134+
" e.printStackTrace();\n" +
134135
" System.exit(1);\n" +
135136
" }\n" +
136137
" }\n" +
@@ -141,7 +142,7 @@ private void replaceLibraryWithExecutableTarget(Path cmakeLists) throws IOExcept
141142
String content = new String(Files.readAllBytes(cmakeLists), StandardCharsets.UTF_8);
142143
String replacement = content.replace(
143144
"add_library(${PROJECT_NAME} ${TRANSLATOR_SOURCES} ${TRANSLATOR_HEADERS})",
144-
"add_executable(${PROJECT_NAME} ${TRANSLATOR_SOURCES} ${TRANSLATOR_HEADERS})\ntarget_link_libraries(${PROJECT_NAME} m)"
145+
"add_executable(${PROJECT_NAME} ${TRANSLATOR_SOURCES} ${TRANSLATOR_HEADERS})\ntarget_link_libraries(${PROJECT_NAME} m objc)"
145146
);
146147
Files.write(cmakeLists, replacement.getBytes(StandardCharsets.UTF_8));
147148
}

vm/tests/src/test/java/com/codename1/tools/translator/HeavyLoadBenchmarkTest.java

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import javax.tools.ToolProvider;
1212
import java.io.File;
1313
import java.io.IOException;
14+
import java.io.UncheckedIOException;
1415
import java.lang.reflect.InvocationTargetException;
1516
import java.lang.reflect.Method;
1617
import java.net.URL;
@@ -23,6 +24,8 @@
2324
import java.util.stream.Collectors;
2425
import java.util.zip.ZipEntry;
2526
import java.util.zip.ZipInputStream;
27+
import java.util.jar.JarEntry;
28+
import java.util.jar.JarOutputStream;
2629

2730
@Tag("benchmark")
2831
public class HeavyLoadBenchmarkTest {
@@ -33,10 +36,7 @@ public class HeavyLoadBenchmarkTest {
3336
@Test
3437
public void benchmarkJavaAPITranslation() throws Exception {
3538
// Locate JavaAPI.jar
36-
Path javaApiJar = Paths.get("..", "JavaAPI", "dist", "JavaAPI.jar").normalize().toAbsolutePath();
37-
if (!Files.exists(javaApiJar)) {
38-
javaApiJar = Paths.get("vm", "JavaAPI", "dist", "JavaAPI.jar").normalize().toAbsolutePath();
39-
}
39+
Path javaApiJar = resolveJavaApiJar();
4040
// Locate CodenameOne Core jar
4141
Path coreJar = findDependencyJar("codenameone-core");
4242

@@ -299,6 +299,94 @@ private Path findPath(String... parts) {
299299
return null;
300300
}
301301

302+
private Path resolveJavaApiJar() throws IOException {
303+
List<Path> candidates = new ArrayList<>();
304+
candidates.add(Paths.get("..", "JavaAPI", "dist", "JavaAPI.jar").normalize().toAbsolutePath());
305+
candidates.add(Paths.get("vm", "JavaAPI", "dist", "JavaAPI.jar").normalize().toAbsolutePath());
306+
candidates.add(firstJarInTarget(Paths.get("..", "JavaAPI", "target")));
307+
candidates.add(firstJarInTarget(Paths.get("vm", "JavaAPI", "target")));
308+
309+
for (Path candidate : candidates) {
310+
if (candidate != null && Files.exists(candidate)) {
311+
return candidate;
312+
}
313+
}
314+
Path srcRoot = findPath("JavaAPI", "src");
315+
if (srcRoot == null) {
316+
srcRoot = findPath("vm", "JavaAPI", "src");
317+
}
318+
Path built = buildJavaApiJar(srcRoot);
319+
if (built != null) {
320+
return built;
321+
}
322+
return candidates.get(0);
323+
}
324+
325+
private Path firstJarInTarget(Path dir) throws IOException {
326+
if (!Files.isDirectory(dir)) {
327+
return null;
328+
}
329+
try (java.util.stream.Stream<Path> stream = Files.list(dir)) {
330+
return stream.filter(p -> p.toString().endsWith(".jar")).findFirst().orElse(null);
331+
}
332+
}
333+
334+
private Path buildJavaApiJar(Path srcRoot) throws IOException {
335+
if (srcRoot == null) {
336+
return null;
337+
}
338+
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
339+
if (compiler == null) {
340+
return null;
341+
}
342+
343+
List<String> sources;
344+
try (java.util.stream.Stream<Path> stream = Files.walk(srcRoot)) {
345+
sources = stream.filter(p -> p.toString().endsWith(".java"))
346+
.map(Path::toString)
347+
.collect(Collectors.toList());
348+
}
349+
if (sources.isEmpty()) {
350+
return null;
351+
}
352+
353+
Path classesDir = Files.createTempDirectory("javaapi-classes");
354+
List<String> args = new ArrayList<>();
355+
args.add("--release");
356+
args.add("11");
357+
args.add("--patch-module");
358+
args.add("java.base=" + srcRoot.toString());
359+
args.add("-Xlint:-options");
360+
args.add("-Xlint:-module");
361+
args.add("-d");
362+
args.add(classesDir.toString());
363+
args.addAll(sources);
364+
365+
int result = compiler.run(null, null, null, args.toArray(new String[0]));
366+
if (result != 0) {
367+
return null;
368+
}
369+
370+
Path jar = Files.createTempFile("JavaAPI-", ".jar");
371+
try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(jar))) {
372+
try (java.util.stream.Stream<Path> stream = Files.walk(classesDir)) {
373+
stream.filter(Files::isRegularFile).forEach(p -> {
374+
JarEntry entry = new JarEntry(classesDir.relativize(p).toString().replace(File.separatorChar, '/'));
375+
try {
376+
jos.putNextEntry(entry);
377+
Files.copy(p, jos);
378+
jos.closeEntry();
379+
} catch (IOException e) {
380+
throw new UncheckedIOException(e);
381+
}
382+
});
383+
}
384+
} catch (UncheckedIOException e) {
385+
throw e.getCause();
386+
}
387+
return jar.toAbsolutePath();
388+
}
389+
302390
private Path findDependencyJar(String namePart) {
303391
Path depsDir = Paths.get("target", "benchmark-dependencies");
304392
if (!Files.exists(depsDir)) return null;

0 commit comments

Comments
 (0)