Use fast lambda calls in scope facade

This commit is contained in:
Sergey Chernov 2026-04-21 16:43:02 +03:00
parent 3721ee8332
commit 6c91b77a85
2 changed files with 23 additions and 0 deletions

View File

@ -66,6 +66,9 @@ internal class ScopeBridge(internal val scope: Scope) : ScopeFacade {
override fun raiseIllegalState(message: String): Nothing = scope.raiseIllegalState(message)
override fun raiseNotImplemented(what: String): Nothing = scope.raiseNotImplemented(what)
override suspend fun call(callee: Obj, args: Arguments, newThisObj: Obj?): Obj {
if (newThisObj == null) {
(callee as? BytecodeArgCallable)?.callWithArgsFast(scope, args)?.let { return it }
}
val child = scope.createChildScope(scope.pos, args = args, newThisObj = newThisObj)
return (callee as? BytecodeCallable)?.callOnFast(child) ?: callee.callOn(child)
}

View File

@ -16,11 +16,13 @@
import kotlinx.coroutines.test.runTest
import net.sergeych.lyng.Compiler
import net.sergeych.lyng.Arguments
import net.sergeych.lyng.Scope
import net.sergeych.lyng.Script
import net.sergeych.lyng.ScriptError
import net.sergeych.lyng.Source
import net.sergeych.lyng.asFacade
import net.sergeych.lyng.obj.ObjInt
import net.sergeych.lyng.obj.ObjString
import net.sergeych.lyng.obj.toInt
import net.sergeych.lyng.pacman.ImportManager
@ -68,6 +70,24 @@ class CompilerVmReviewRegressionTest {
assertContains(ex.errorMessage, "module binding 'answer'")
}
@Test
fun facadeCallUsesPreparedLambdaWithArgs() = runTest {
val lambda = Compiler.compile(
Source(
"<facade-call-lambda>",
"""
val base = 2
{ x -> x + base }
""".trimIndent()
),
Script.defaultImportManager
)
val scope = Script.newScope()
val callable = lambda.execute(scope)
assertEquals(42, scope.asFacade().call(callable, Arguments(ObjInt.of(40))).toInt())
}
@Test
fun subjectlessWhenReportsScriptError() = runTest {
val ex = assertFailsWith<ScriptError> {