diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/ClassStaticFieldInitStatement.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/ClassStaticFieldInitStatement.kt index 554da63..2a857a7 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/ClassStaticFieldInitStatement.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/ClassStaticFieldInitStatement.kt @@ -37,7 +37,8 @@ class ClassStaticFieldInitStatement( override val pos: Pos = startPos override suspend fun execute(scope: Scope): Obj { - val initValue = initializer?.execute(scope)?.byValueCopy() ?: ObjNull + val initValue = initializer?.let { execBytecodeOnly(scope, it, "class static field init") }?.byValueCopy() + ?: ObjNull val cls = scope.thisObj as? ObjClass ?: scope.raiseIllegalState("static field init requires class scope") return if (isDelegated) { @@ -98,4 +99,13 @@ class ClassStaticFieldInitStatement( initValue } } + + private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj { + val bytecode = when (stmt) { + is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt + is BytecodeBodyProvider -> stmt.bytecodeBody() + else -> null + } ?: scope.raiseIllegalState("$label requires bytecode statement") + return bytecode.execute(scope) + } } diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/InstanceInitStatements.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/InstanceInitStatements.kt index eeedc0a..2883a34 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/InstanceInitStatements.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/InstanceInitStatements.kt @@ -38,7 +38,7 @@ class InstanceFieldInitStatement( override val pos: Pos, ) : Statement() { override suspend fun execute(scope: Scope): Obj { - val initValue = initializer?.execute(scope)?.byValueCopy() + val initValue = initializer?.let { execBytecodeOnly(scope, it, "instance field init") }?.byValueCopy() ?: if (isLateInitVal) ObjUnset else ObjNull scope.addItem( storageName, @@ -54,6 +54,15 @@ class InstanceFieldInitStatement( ) return ObjVoid } + + private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj { + val bytecode = when (stmt) { + is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt + is BytecodeBodyProvider -> stmt.bytecodeBody() + else -> null + } ?: scope.raiseIllegalState("$label requires bytecode statement") + return bytecode.execute(scope) + } } class InstancePropertyInitStatement( @@ -100,7 +109,7 @@ class InstanceDelegatedInitStatement( override val pos: Pos, ) : Statement() { override suspend fun execute(scope: Scope): Obj { - val initValue = initializer.execute(scope) + val initValue = execBytecodeOnly(scope, initializer, "instance delegated init") val accessType = ObjString(accessTypeLabel) val finalDelegate = try { initValue.invokeInstanceMethod( @@ -127,4 +136,13 @@ class InstanceDelegatedInitStatement( } return ObjVoid } + + private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj { + val bytecode = when (stmt) { + is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt + is BytecodeBodyProvider -> stmt.bytecodeBody() + else -> null + } ?: scope.raiseIllegalState("$label requires bytecode statement") + return bytecode.execute(scope) + } }