Enforce bytecode-only class and instance init bodies
This commit is contained in:
parent
70ba424ef9
commit
05cba5b653
@ -37,7 +37,8 @@ class ClassStaticFieldInitStatement(
|
|||||||
override val pos: Pos = startPos
|
override val pos: Pos = startPos
|
||||||
|
|
||||||
override suspend fun execute(scope: Scope): Obj {
|
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
|
val cls = scope.thisObj as? ObjClass
|
||||||
?: scope.raiseIllegalState("static field init requires class scope")
|
?: scope.raiseIllegalState("static field init requires class scope")
|
||||||
return if (isDelegated) {
|
return if (isDelegated) {
|
||||||
@ -98,4 +99,13 @@ class ClassStaticFieldInitStatement(
|
|||||||
initValue
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class InstanceFieldInitStatement(
|
|||||||
override val pos: Pos,
|
override val pos: Pos,
|
||||||
) : Statement() {
|
) : Statement() {
|
||||||
override suspend fun execute(scope: Scope): Obj {
|
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
|
?: if (isLateInitVal) ObjUnset else ObjNull
|
||||||
scope.addItem(
|
scope.addItem(
|
||||||
storageName,
|
storageName,
|
||||||
@ -54,6 +54,15 @@ class InstanceFieldInitStatement(
|
|||||||
)
|
)
|
||||||
return ObjVoid
|
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(
|
class InstancePropertyInitStatement(
|
||||||
@ -100,7 +109,7 @@ class InstanceDelegatedInitStatement(
|
|||||||
override val pos: Pos,
|
override val pos: Pos,
|
||||||
) : Statement() {
|
) : Statement() {
|
||||||
override suspend fun execute(scope: Scope): Obj {
|
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 accessType = ObjString(accessTypeLabel)
|
||||||
val finalDelegate = try {
|
val finalDelegate = try {
|
||||||
initValue.invokeInstanceMethod(
|
initValue.invokeInstanceMethod(
|
||||||
@ -127,4 +136,13 @@ class InstanceDelegatedInitStatement(
|
|||||||
}
|
}
|
||||||
return ObjVoid
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user