diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ProgramInterpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ProgramInterpreter.kt index b84efdde3..dab3581e2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ProgramInterpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ProgramInterpreter.kt @@ -1,8 +1,15 @@ package com.smeup.rpgparser.interpreter +import com.smeup.rpgparser.execution.MainExecutionContext + class ProgramInterpreter(val systemInterface: SystemInterface) { fun execute(rpgProgram: RpgProgram, initialValues: LinkedHashMap) { - rpgProgram.execute(systemInterface = systemInterface, params = initialValues) + MainExecutionContext.getProgramStack().push(rpgProgram) + try { + rpgProgram.execute(systemInterface = systemInterface, params = initialValues) + } finally { + MainExecutionContext.getProgramStack().pop() + } } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index fb213ad78..079cc62e2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -128,8 +128,20 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " 1) { + val parentProgramIndex = programStack.lastIndex - 1 + programStack[parentProgramIndex] } else { null } @@ -149,7 +161,6 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " @@ -803,6 +806,9 @@ data class CallStmt( currentParam.result?.let { interpreter.assign(it, value) } } } + + if (program is RpgProgram) + MainExecutionContext.getProgramStack().pop() } override fun getStatementLogRenderer(source: LogSourceProvider, action: String): LazyLogEntry { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index 154e84ad7..93837a25d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -397,6 +397,16 @@ open class MULANGT10BaseCodopTest : MULANGTTest() { assertEquals(expected, "smeup/MUDRNRAPU00268".outputOf(configuration = smeupConfig)) } + /** + * State of context after a CALL stack failed setting an error indicator + * @see #LS24004538 + */ + @Test + fun executeMUDRNRAPU00269() { + val expected = listOf("ok") + assertEquals(expected, "smeup/MUDRNRAPU00269".outputOf(configuration = smeupConfig)) + } + /** * Comparing number and `*ZEROS` by using `IFxx`. * @see #LS24004528 diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/ERRORPGM2.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/ERRORPGM2.rpgle new file mode 100644 index 000000000..fb2b84d08 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/ERRORPGM2.rpgle @@ -0,0 +1,2 @@ + * This program has the sole purpose of calling a program that throws a runtime exception + C CALL 'ERRORPGM' \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00268.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00268.rpgle index 1200cf176..4f7873ac4 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00268.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00268.rpgle @@ -22,7 +22,7 @@ D £TESTDS DS D £TESTPA 10 - * Call of a program that throws an error and setting the error indicator + * Call of a program that throws an error and sets the error indicator C CALL 'ERRORPGM' 35 * If call failed but the error indicator was set diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00269.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00269.rpgle new file mode 100644 index 000000000..fa43d3cd5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00269.rpgle @@ -0,0 +1,38 @@ + V* ============================================================== + V* 30/10/2024 APU002 Creation + V* ============================================================== + O * PROGRAM GOAL + O * Call a program with an error indicator that calls another program + O * that throws an error and ensure the execution context is appropriate + V* ============================================================== + O * JARIKO ANOMALY + O * Before the fix, the error was about the caller not resolving + O * symbols in the correct compilation unit + O * + O * Note: see MUDRNRAPU00268.rpgle for a deeper explanation + O * on how the error was reproduced + V* ============================================================== + + * Test declarations + D £TESTDS DS + D £TESTPA 10 + + * Call of a program that throws an error and sets the error indicator + C CALL 'ERRORPGM2' 35 + + * If call failed but the error indicator was set + * Execution should continue and the context should reference the correct program + C IF P_Test(£TESTPA:'EmiMsg(':'')='Y' + C 'ok' DSPLY + C ENDIF + + * Test procedure + PP_Test B + D P_Test Pi 30000 VARYING + D $A 15 CONST + D $B 1N OPTIONS(*NOPASS) + D $C 1 OPTIONS(*NOPASS) + C RETURN 'Y' + P E + + C SETON LR