Add bytecode opcode for ValueFnRef
This commit is contained in:
parent
a4fc5ac6d5
commit
81d86f4c3a
@ -175,7 +175,13 @@ class BytecodeCompiler(
|
|||||||
CompiledValue(mapped, resolved)
|
CompiledValue(mapped, resolved)
|
||||||
}
|
}
|
||||||
is LocalVarRef -> compileNameLookup(ref.name)
|
is LocalVarRef -> compileNameLookup(ref.name)
|
||||||
is ValueFnRef -> compileEvalRef(ref)
|
is ValueFnRef -> {
|
||||||
|
val constId = builder.addConst(BytecodeConst.ValueFn(ref.valueFn()))
|
||||||
|
val slot = allocSlot()
|
||||||
|
builder.emit(Opcode.EVAL_VALUE_FN, constId, slot)
|
||||||
|
updateSlotType(slot, SlotType.OBJ)
|
||||||
|
CompiledValue(slot, SlotType.OBJ)
|
||||||
|
}
|
||||||
is ListLiteralRef -> compileListLiteral(ref)
|
is ListLiteralRef -> compileListLiteral(ref)
|
||||||
is ThisMethodSlotCallRef -> compileThisMethodSlotCall(ref)
|
is ThisMethodSlotCallRef -> compileThisMethodSlotCall(ref)
|
||||||
is StatementRef -> {
|
is StatementRef -> {
|
||||||
|
|||||||
@ -32,6 +32,7 @@ sealed class BytecodeConst {
|
|||||||
data class Ref(val value: net.sergeych.lyng.obj.ObjRef) : BytecodeConst()
|
data class Ref(val value: net.sergeych.lyng.obj.ObjRef) : BytecodeConst()
|
||||||
data class StatementVal(val statement: net.sergeych.lyng.Statement) : BytecodeConst()
|
data class StatementVal(val statement: net.sergeych.lyng.Statement) : BytecodeConst()
|
||||||
data class ListLiteralPlan(val spreads: List<Boolean>) : BytecodeConst()
|
data class ListLiteralPlan(val spreads: List<Boolean>) : BytecodeConst()
|
||||||
|
data class ValueFn(val fn: suspend (net.sergeych.lyng.Scope) -> net.sergeych.lyng.obj.ObjRecord) : BytecodeConst()
|
||||||
data class SlotPlan(val plan: Map<String, Int>) : BytecodeConst()
|
data class SlotPlan(val plan: Map<String, Int>) : BytecodeConst()
|
||||||
data class ExtensionPropertyDecl(
|
data class ExtensionPropertyDecl(
|
||||||
val extTypeName: String,
|
val extTypeName: String,
|
||||||
|
|||||||
@ -184,7 +184,7 @@ class CmdBuilder {
|
|||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.LIST_LITERAL ->
|
Opcode.LIST_LITERAL ->
|
||||||
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
||||||
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT ->
|
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
||||||
listOf(OperandKind.ID, OperandKind.SLOT)
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,6 +377,7 @@ class CmdBuilder {
|
|||||||
Opcode.EVAL_FALLBACK -> CmdEvalFallback(operands[0], operands[1])
|
Opcode.EVAL_FALLBACK -> CmdEvalFallback(operands[0], operands[1])
|
||||||
Opcode.EVAL_REF -> CmdEvalRef(operands[0], operands[1])
|
Opcode.EVAL_REF -> CmdEvalRef(operands[0], operands[1])
|
||||||
Opcode.EVAL_STMT -> CmdEvalStmt(operands[0], operands[1])
|
Opcode.EVAL_STMT -> CmdEvalStmt(operands[0], operands[1])
|
||||||
|
Opcode.EVAL_VALUE_FN -> CmdEvalValueFn(operands[0], operands[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -187,6 +187,7 @@ object CmdDisassembler {
|
|||||||
is CmdEvalFallback -> Opcode.EVAL_FALLBACK to intArrayOf(cmd.id, cmd.dst)
|
is CmdEvalFallback -> Opcode.EVAL_FALLBACK to intArrayOf(cmd.id, cmd.dst)
|
||||||
is CmdEvalRef -> Opcode.EVAL_REF to intArrayOf(cmd.id, cmd.dst)
|
is CmdEvalRef -> Opcode.EVAL_REF to intArrayOf(cmd.id, cmd.dst)
|
||||||
is CmdEvalStmt -> Opcode.EVAL_STMT to intArrayOf(cmd.id, cmd.dst)
|
is CmdEvalStmt -> Opcode.EVAL_STMT to intArrayOf(cmd.id, cmd.dst)
|
||||||
|
is CmdEvalValueFn -> Opcode.EVAL_VALUE_FN to intArrayOf(cmd.id, cmd.dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +269,7 @@ object CmdDisassembler {
|
|||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.LIST_LITERAL ->
|
Opcode.LIST_LITERAL ->
|
||||||
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
||||||
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT ->
|
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
||||||
listOf(OperandKind.ID, OperandKind.SLOT)
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1352,6 +1352,22 @@ class CmdEvalStmt(internal val id: Int, internal val dst: Int) : Cmd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CmdEvalValueFn(internal val id: Int, internal val dst: Int) : Cmd() {
|
||||||
|
override suspend fun perform(frame: CmdFrame) {
|
||||||
|
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||||
|
frame.syncFrameToScope()
|
||||||
|
}
|
||||||
|
val valueFn = frame.fn.constants.getOrNull(id) as? BytecodeConst.ValueFn
|
||||||
|
?: error("EVAL_VALUE_FN expects ValueFn at $id")
|
||||||
|
val result = valueFn.fn(frame.scope).value
|
||||||
|
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||||
|
frame.syncScopeToFrame()
|
||||||
|
}
|
||||||
|
frame.storeObjResult(dst, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CmdFrame(
|
class CmdFrame(
|
||||||
val vm: CmdVm,
|
val vm: CmdVm,
|
||||||
val fn: CmdFunction,
|
val fn: CmdFunction,
|
||||||
|
|||||||
@ -145,6 +145,7 @@ enum class Opcode(val code: Int) {
|
|||||||
THROW(0xBB),
|
THROW(0xBB),
|
||||||
EVAL_REF(0xBC),
|
EVAL_REF(0xBC),
|
||||||
EVAL_STMT(0xBD),
|
EVAL_STMT(0xBD),
|
||||||
|
EVAL_VALUE_FN(0xBE),
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@ -66,6 +66,8 @@ sealed interface ObjRef {
|
|||||||
|
|
||||||
/** Runtime-computed read-only reference backed by a lambda. */
|
/** Runtime-computed read-only reference backed by a lambda. */
|
||||||
class ValueFnRef(private val fn: suspend (Scope) -> ObjRecord) : ObjRef {
|
class ValueFnRef(private val fn: suspend (Scope) -> ObjRecord) : ObjRef {
|
||||||
|
internal fun valueFn(): suspend (Scope) -> ObjRecord = fn
|
||||||
|
|
||||||
override suspend fun get(scope: Scope): ObjRecord = fn(scope)
|
override suspend fun get(scope: Scope): ObjRecord = fn(scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user