diff --git a/vm/tests/src/test/java/com/codename1/tools/translator/BytecodeInstructionIntegrationTest.java b/vm/tests/src/test/java/com/codename1/tools/translator/BytecodeInstructionIntegrationTest.java index 2190b6281c..71e252f39e 100644 --- a/vm/tests/src/test/java/com/codename1/tools/translator/BytecodeInstructionIntegrationTest.java +++ b/vm/tests/src/test/java/com/codename1/tools/translator/BytecodeInstructionIntegrationTest.java @@ -70,6 +70,8 @@ void translatesOptimizedBytecodeToLLVMExecutable() throws Exception { assertTrue(generatedCode.contains("CustomJump */"), "Optimized comparisons should emit CustomJump code"); assertTrue(generatedCode.contains("BC_IINC"), "Increment operations should translate to BC_IINC macro"); assertTrue(generatedCode.contains("VarOp.assignFrom"), "Optimized stores should rely on CustomIntruction output"); + assertTrue(generatedCode.contains("switch((*SP).data.i)"), "SwitchInstruction should emit a native switch statement"); + assertTrue(generatedCode.contains("BC_DUP(); /* DUP */"), "DupExpression should translate DUP operations to BC_DUP"); CleanTargetIntegrationTest.replaceLibraryWithExecutableTarget(cmakeLists, srcRoot.getFileName().toString()); @@ -88,7 +90,7 @@ void translatesOptimizedBytecodeToLLVMExecutable() throws Exception { Path executable = buildDir.resolve("CustomBytecodeApp"); String output = CleanTargetIntegrationTest.runCommand(Arrays.asList(executable.toString()), buildDir); - assertTrue(output.contains("RESULT=14"), "Compiled program should print the expected arithmetic result"); + assertTrue(output.contains("RESULT=54"), "Compiled program should print the expected arithmetic result"); } private Path findGeneratedSource(Path srcRoot) throws Exception { @@ -116,10 +118,30 @@ private String appSource() { " int result = min + counter;\n" + " return result;\n" + " }\n" + + " private static int switchComputation(int value) {\n" + + " switch (value) {\n" + + " case 4:\n" + + " return value + 10;\n" + + " case 10:\n" + + " return value + 5;\n" + + " default:\n" + + " return value - 1;\n" + + " }\n" + + " }\n" + + " private static int synchronizedIncrement(int base) {\n" + + " Object lock = new Object();\n" + + " int result = base;\n" + + " synchronized (lock) {\n" + + " result++;\n" + + " }\n" + + " return result;\n" + + " }\n" + " public static void main(String[] args) {\n" + " int first = optimizedComputation(1, 3);\n" + " int second = optimizedComputation(5, 2);\n" + - " report(first + second);\n" + + " int switched = switchComputation(first) + switchComputation(second);\n" + + " int synchronizedValue = synchronizedIncrement(second);\n" + + " report(first + second + switched + synchronizedValue);\n" + " }\n" + "}\n"; } diff --git a/vm/tests/src/test/java/com/codename1/tools/translator/CleanTargetIntegrationTest.java b/vm/tests/src/test/java/com/codename1/tools/translator/CleanTargetIntegrationTest.java index 80c791ed0e..090cd5e53e 100644 --- a/vm/tests/src/test/java/com/codename1/tools/translator/CleanTargetIntegrationTest.java +++ b/vm/tests/src/test/java/com/codename1/tools/translator/CleanTargetIntegrationTest.java @@ -171,6 +171,10 @@ static void patchCn1Globals(Path srcRoot) throws IOException { content = content.replace("#ifdef __OBJC__\n", "#ifdef __OBJC__\n@class NSString;\n"); Files.write(cn1Globals, content.getBytes(StandardCharsets.UTF_8)); } + if (!content.contains("#include ")) { + content = content.replace("#include \n", "#include \n#include \n"); + Files.write(cn1Globals, content.getBytes(StandardCharsets.UTF_8)); + } } static void writeRuntimeStubs(Path srcRoot) throws IOException { @@ -187,11 +191,12 @@ static void writeRuntimeStubs(Path srcRoot) throws IOException { "\n" + "static void initThreadState() {\n" + " memset(&globalThreadData, 0, sizeof(globalThreadData));\n" + - " globalThreadData.threadObjectStack = calloc(64, sizeof(struct elementStruct));\n" + - " globalThreadData.pendingHeapAllocations = calloc(64, sizeof(void*));\n" + - " globalThreadData.callStackClass = calloc(64, sizeof(int));\n" + - " globalThreadData.callStackLine = calloc(64, sizeof(int));\n" + - " globalThreadData.callStackMethod = calloc(64, sizeof(int));\n" + + " globalThreadData.blocks = calloc(CN1_MAX_STACK_CALL_DEPTH, sizeof(struct TryBlock));\n" + + " globalThreadData.threadObjectStack = calloc(CN1_MAX_OBJECT_STACK_DEPTH, sizeof(struct elementStruct));\n" + + " globalThreadData.pendingHeapAllocations = calloc(CN1_MAX_OBJECT_STACK_DEPTH, sizeof(void*));\n" + + " globalThreadData.callStackClass = calloc(CN1_MAX_STACK_CALL_DEPTH, sizeof(int));\n" + + " globalThreadData.callStackLine = calloc(CN1_MAX_STACK_CALL_DEPTH, sizeof(int));\n" + + " globalThreadData.callStackMethod = calloc(CN1_MAX_STACK_CALL_DEPTH, sizeof(int));\n" + "}\n" + "\n" + "struct ThreadLocalData* getThreadLocalData() {\n" + @@ -237,6 +242,22 @@ static void writeRuntimeStubs(Path srcRoot) throws IOException { "\n" + "void monitorExit(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT obj) { (void)obj; }\n" + "\n" + + "struct elementStruct* pop(struct elementStruct** sp) {\n" + + " (*sp)--;\n" + + " return *sp;\n" + + "}\n" + + "\n" + + "void popMany(CODENAME_ONE_THREAD_STATE, int count, struct elementStruct** sp) {\n" + + " while (count-- > 0) {\n" + + " (*sp)--;\n" + + " }\n" + + "}\n" + + "\n" + + "void throwException(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT obj) {\n" + + " (void)obj;\n" + + " exit(1);\n" + + "}\n" + + "\n" + "struct clazz class__java_lang_Class = {0};\n" + "int currentGcMarkValue = 1;\n";