Add bytecode opcode for ValueFnRef
This commit is contained in:
parent
a4fc5ac6d5
commit
81d86f4c3a
@ -175,7 +175,13 @@ class BytecodeCompiler(
|
||||
CompiledValue(mapped, resolved)
|
||||
}
|
||||
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 ThisMethodSlotCallRef -> compileThisMethodSlotCall(ref)
|
||||
is StatementRef -> {
|
||||
|
||||
@ -32,6 +32,7 @@ sealed class BytecodeConst {
|
||||
data class Ref(val value: net.sergeych.lyng.obj.ObjRef) : BytecodeConst()
|
||||
data class StatementVal(val statement: net.sergeych.lyng.Statement) : 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 ExtensionPropertyDecl(
|
||||
val extTypeName: String,
|
||||
|
||||
@ -184,7 +184,7 @@ class CmdBuilder {
|
||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||
Opcode.LIST_LITERAL ->
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -377,6 +377,7 @@ class CmdBuilder {
|
||||
Opcode.EVAL_FALLBACK -> CmdEvalFallback(operands[0], operands[1])
|
||||
Opcode.EVAL_REF -> CmdEvalRef(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 CmdEvalRef -> Opcode.EVAL_REF 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)
|
||||
Opcode.LIST_LITERAL ->
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(
|
||||
val vm: CmdVm,
|
||||
val fn: CmdFunction,
|
||||
|
||||
@ -145,6 +145,7 @@ enum class Opcode(val code: Int) {
|
||||
THROW(0xBB),
|
||||
EVAL_REF(0xBC),
|
||||
EVAL_STMT(0xBD),
|
||||
EVAL_VALUE_FN(0xBE),
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
||||
@ -66,6 +66,8 @@ sealed interface ObjRef {
|
||||
|
||||
/** Runtime-computed read-only reference backed by a lambda. */
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user