diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/CmdRuntime.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/CmdRuntime.kt index 123411b..7e7c6fe 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/CmdRuntime.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/CmdRuntime.kt @@ -3291,13 +3291,16 @@ class CmdCallDirect( } } val result = if (PerfFlags.SCOPE_POOL) { - frame.ensureScope().withChildFrame(args) { child -> callee.callOn(child) } + frame.ensureScope().withChildFrame(args) { child -> + (callee as? BytecodeCallable)?.callOnFast(child) ?: callee.callOn(child) + } } else { val scope = frame.ensureScope() if (callee is BytecodeLambdaCallable && callee.supportsDirectInvokeFastPath()) { callee.invokeWithArgsFast(scope, args) ?: callee.invokeWithArgs(scope, args) } else { - callee.callOn(scope.createChildScope(scope.pos, args = args)) + val child = scope.createChildScope(scope.pos, args = args) + (callee as? BytecodeCallable)?.callOnFast(child) ?: callee.callOn(child) } } frame.storeObjResult(dst, result) @@ -3327,7 +3330,9 @@ class CmdCallSlot( val args = frame.buildArguments(argBase, argCount) val canPool = PerfFlags.SCOPE_POOL && callee !is Statement val result = if (canPool) { - frame.ensureScope().withChildFrame(args) { child -> callee.callOn(child) } + frame.ensureScope().withChildFrame(args) { child -> + (callee as? BytecodeCallable)?.callOnFast(child) ?: callee.callOn(child) + } } else { val scope = frame.ensureScope() if (callee is Statement) { @@ -3339,7 +3344,8 @@ class CmdCallSlot( if (callee is BytecodeLambdaCallable && callee.supportsDirectInvokeFastPath()) { callee.invokeWithArgsFast(scope, args) ?: callee.invokeWithArgs(scope, args) } else { - callee.callOn(scope.createChildScope(scope.pos, args = args)) + val child = scope.createChildScope(scope.pos, args = args) + (callee as? BytecodeCallable)?.callOnFast(child) ?: callee.callOn(child) } } frame.storeObjResult(dst, result) @@ -3429,7 +3435,8 @@ class CmdListFillInt( callable.invokeWithArgsFast(scope, Arguments(ObjInt.of(i.toLong()))) ?: callable.invokeWithArgs(scope, Arguments(ObjInt.of(i.toLong()))) } else { - callable.callOn(scope.createChildScope(scope.pos, args = Arguments(ObjInt.of(i.toLong())))) + val child = scope.createChildScope(scope.pos, args = Arguments(ObjInt.of(i.toLong()))) + (callable as? BytecodeCallable)?.callOnFast(child) ?: callable.callOn(child) } val intValue = (value as? ObjInt)?.value ?: scope.raiseClassCastError("expected Int fill result") result.setIntAtFast(i, intValue) diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjProperty.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjProperty.kt index 2ac1f68..a653bab 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjProperty.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjProperty.kt @@ -18,6 +18,7 @@ package net.sergeych.lyng.obj import net.sergeych.lyng.Arguments +import net.sergeych.lyng.BytecodeCallable import net.sergeych.lyng.BytecodeBodyProvider import net.sergeych.lyng.Scope import net.sergeych.lyng.Statement @@ -41,14 +42,16 @@ class ObjProperty( val instanceScope = (instance as? ObjInstance)?.instanceScope ?: instance.autoInstanceScope(scope) val execScope = scope.applyClosure(instanceScope).createChildScope(newThisObj = instance) execScope.currentClassCtx = declaringClass + (g as? BytecodeCallable)?.callOnFast(execScope)?.let { return it } return when (g) { is BytecodeStatement -> executeBytecodeWithSeed(execScope, g, "property getter") is BytecodeBodyProvider -> { val body = g.bytecodeBody() - if (body != null) executeBytecodeWithSeed(execScope, body, "property getter") else g.callOn(execScope) + if (body != null) executeBytecodeWithSeed(execScope, body, "property getter") + else (g as? BytecodeCallable)?.callOnFast(execScope) ?: g.callOn(execScope) } - is Statement -> g.callOn(execScope) - else -> g.callOn(execScope) + is Statement -> (g as? BytecodeCallable)?.callOnFast(execScope) ?: g.callOn(execScope) + else -> (g as? BytecodeCallable)?.callOnFast(execScope) ?: g.callOn(execScope) } } @@ -59,14 +62,16 @@ class ObjProperty( val instanceScope = (instance as? ObjInstance)?.instanceScope ?: instance.autoInstanceScope(scope) val execScope = scope.applyClosure(instanceScope).createChildScope(args = Arguments(value), newThisObj = instance) execScope.currentClassCtx = declaringClass + (s as? BytecodeCallable)?.callOnFast(execScope)?.let { return } when (s) { is BytecodeStatement -> executeBytecodeWithSeed(execScope, s, "property setter") is BytecodeBodyProvider -> { val body = s.bytecodeBody() - if (body != null) executeBytecodeWithSeed(execScope, body, "property setter") else s.callOn(execScope) + if (body != null) executeBytecodeWithSeed(execScope, body, "property setter") + else (s as? BytecodeCallable)?.callOnFast(execScope) ?: s.callOn(execScope) } - is Statement -> s.callOn(execScope) - else -> s.callOn(execScope) + is Statement -> (s as? BytecodeCallable)?.callOnFast(execScope) ?: s.callOn(execScope) + else -> (s as? BytecodeCallable)?.callOnFast(execScope) ?: s.callOn(execScope) } }