diff --git a/engine/runtime-instrument-common/src/main/java/org/enso/interpreter/service/ExecutionService.java b/engine/runtime-instrument-common/src/main/java/org/enso/interpreter/service/ExecutionService.java index 962062b00c..802e7c9d10 100644 --- a/engine/runtime-instrument-common/src/main/java/org/enso/interpreter/service/ExecutionService.java +++ b/engine/runtime-instrument-common/src/main/java/org/enso/interpreter/service/ExecutionService.java @@ -72,7 +72,7 @@ public final class ExecutionService { private final EnsoContext context; private final Optional idExecutionInstrument; private final NotificationHandler.Forwarder notificationForwarder; - private final TruffleLogger logger = TruffleLogger.getLogger(LanguageInfo.ID); + private final TruffleLogger logger = TruffleLogger.getLogger(LanguageInfo.ID, ExecutionService.class); private final ConnectedLockManager connectedLockManager; private final ExecuteRootNode execute = new ExecuteRootNode(); private final CallRootNode call = new CallRootNode(); diff --git a/engine/runtime-instrument-id-execution/src/main/java/org/enso/interpreter/instrument/IdExecutionInstrument.java b/engine/runtime-instrument-id-execution/src/main/java/org/enso/interpreter/instrument/IdExecutionInstrument.java index f4b0c426e0..44020acfad 100644 --- a/engine/runtime-instrument-id-execution/src/main/java/org/enso/interpreter/instrument/IdExecutionInstrument.java +++ b/engine/runtime-instrument-id-execution/src/main/java/org/enso/interpreter/instrument/IdExecutionInstrument.java @@ -234,7 +234,7 @@ public class IdExecutionInstrument extends TruffleInstrument implements IdExecut functionCallInstrumentationNode.getId(), result, nanoTimeElapsed, - frame.materialize(), + frame == null ? null : frame.materialize(), node); Object cachedResult = callbacks.onFunctionReturn(info); if (cachedResult != null) { @@ -243,7 +243,7 @@ public class IdExecutionInstrument extends TruffleInstrument implements IdExecut } else if (node instanceof ExpressionNode expressionNode) { Info info = new NodeInfo( - expressionNode.getId(), result, nanoTimeElapsed, frame.materialize(), node); + expressionNode.getId(), result, nanoTimeElapsed, frame == null ? null : frame.materialize(), node); callbacks.updateCachedResult(info); if (info.isPanic()) { diff --git a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala index 1c3ca7694d..b70dd2957f 100644 --- a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala +++ b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala @@ -6535,4 +6535,66 @@ class RuntimeServerTest .name } + it should "handle tailcalls" in { + val contextId = UUID.randomUUID() + val requestId = UUID.randomUUID() + val moduleName = "Enso_Test.Test.Main" + val metadata = new Metadata + val code = + """main = + | fac 10 + | + |fac n = + | acc n v = if n <= 1 then v else + | @Tail_Call acc n-1 n*v + | + | acc n 1 + |""".stripMargin.linesIterator.mkString("\n") + + val res = metadata.addItem(11, 6, "aa") + + val contents = metadata.appendToCode(code) + val mainFile = context.writeMain(contents) + + // create context + context.send(Api.Request(requestId, Api.CreateContextRequest(contextId))) + context.receive shouldEqual Some( + Api.Response(requestId, Api.CreateContextResponse(contextId)) + ) + + // Set sources for the module + context.send( + Api.Request(requestId, Api.OpenFileRequest(mainFile, contents)) + ) + context.receive shouldEqual Some( + Api.Response(Some(requestId), Api.OpenFileResponse) + ) + + // push main + context.send( + Api.Request( + requestId, + Api.PushContextRequest( + contextId, + Api.StackItem.ExplicitCall( + Api.MethodPointer(moduleName, moduleName, "main"), + None, + Vector() + ) + ) + ) + ) + context.receiveN(3) should contain theSameElementsAs Seq( + Api.Response(requestId, Api.PushContextResponse(contextId)), + TestMessages.update( + contextId, + res, + ConstantsGen.INTEGER_BUILTIN, + methodCall = + Some(Api.MethodCall(Api.MethodPointer(moduleName, moduleName, "fac"))) + ), + context.executionComplete(contextId) + ) + } + } diff --git a/lib/scala/logging-service-logback/src/main/java/org/enso/logger/ApplicationFilter.java b/lib/scala/logging-service-logback/src/main/java/org/enso/logger/ApplicationFilter.java index 7c2af871b1..49f7b6cfe7 100644 --- a/lib/scala/logging-service-logback/src/main/java/org/enso/logger/ApplicationFilter.java +++ b/lib/scala/logging-service-logback/src/main/java/org/enso/logger/ApplicationFilter.java @@ -23,7 +23,7 @@ public class ApplicationFilter extends Filter { this.loggers = loggers; this.level = level; this.prefix = prefix; - this.prefixLength = prefix != null ? prefix.length() + 1 : 0; // inlude `.` in `enso.` + this.prefixLength = prefix != null ? prefix.length() : 0; } @Override @@ -48,7 +48,9 @@ public class ApplicationFilter extends Filter { private boolean loggerNameMatches(String validLoggerName, String eventLoggerName) { if (prefix != null && eventLoggerName.startsWith(prefix)) { - return eventLoggerName.substring(prefixLength).startsWith(validLoggerName); + int normalizedLoggerNameIdx = + eventLoggerName.indexOf(".") == prefixLength ? prefixLength + 1 : prefixLength; + return eventLoggerName.substring(normalizedLoggerNameIdx).startsWith(validLoggerName); } else { return eventLoggerName.startsWith(validLoggerName); }