Add bytecode opcodes for implicit this member access
This commit is contained in:
parent
81d86f4c3a
commit
938503fdd4
@ -202,7 +202,13 @@ class BytecodeCompiler(
|
|||||||
is CallRef -> compileCall(ref)
|
is CallRef -> compileCall(ref)
|
||||||
is MethodCallRef -> compileMethodCall(ref)
|
is MethodCallRef -> compileMethodCall(ref)
|
||||||
is FieldRef -> compileFieldRef(ref)
|
is FieldRef -> compileFieldRef(ref)
|
||||||
is ImplicitThisMemberRef -> compileEvalRef(ref)
|
is ImplicitThisMemberRef -> {
|
||||||
|
val nameId = builder.addConst(BytecodeConst.StringVal(ref.name))
|
||||||
|
val slot = allocSlot()
|
||||||
|
builder.emit(Opcode.GET_THIS_MEMBER, nameId, slot)
|
||||||
|
updateSlotType(slot, SlotType.OBJ)
|
||||||
|
CompiledValue(slot, SlotType.OBJ)
|
||||||
|
}
|
||||||
is ImplicitThisMethodCallRef -> compileEvalRef(ref)
|
is ImplicitThisMethodCallRef -> compileEvalRef(ref)
|
||||||
is IndexRef -> compileIndexRef(ref)
|
is IndexRef -> compileIndexRef(ref)
|
||||||
else -> null
|
else -> null
|
||||||
@ -880,6 +886,12 @@ class BytecodeCompiler(
|
|||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
if (target is ImplicitThisMemberRef) {
|
||||||
|
val nameId = builder.addConst(BytecodeConst.StringVal(target.name))
|
||||||
|
if (nameId > 0xFFFF) return null
|
||||||
|
builder.emit(Opcode.SET_THIS_MEMBER, nameId, value.slot)
|
||||||
|
return value
|
||||||
|
}
|
||||||
if (target is IndexRef) {
|
if (target is IndexRef) {
|
||||||
val receiver = compileRefWithFallback(target.targetRef, null, Pos.builtIn) ?: return null
|
val receiver = compileRefWithFallback(target.targetRef, null, Pos.builtIn) ?: return null
|
||||||
if (!target.optionalRef) {
|
if (!target.optionalRef) {
|
||||||
|
|||||||
@ -184,6 +184,10 @@ 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.GET_THIS_MEMBER ->
|
||||||
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
|
Opcode.SET_THIS_MEMBER ->
|
||||||
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
||||||
listOf(OperandKind.ID, OperandKind.SLOT)
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
}
|
}
|
||||||
@ -374,6 +378,8 @@ class CmdBuilder {
|
|||||||
Opcode.GET_INDEX -> CmdGetIndex(operands[0], operands[1], operands[2])
|
Opcode.GET_INDEX -> CmdGetIndex(operands[0], operands[1], operands[2])
|
||||||
Opcode.SET_INDEX -> CmdSetIndex(operands[0], operands[1], operands[2])
|
Opcode.SET_INDEX -> CmdSetIndex(operands[0], operands[1], operands[2])
|
||||||
Opcode.LIST_LITERAL -> CmdListLiteral(operands[0], operands[1], operands[2], operands[3])
|
Opcode.LIST_LITERAL -> CmdListLiteral(operands[0], operands[1], operands[2], operands[3])
|
||||||
|
Opcode.GET_THIS_MEMBER -> CmdGetThisMember(operands[0], operands[1])
|
||||||
|
Opcode.SET_THIS_MEMBER -> CmdSetThisMember(operands[0], operands[1])
|
||||||
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])
|
||||||
|
|||||||
@ -184,6 +184,8 @@ object CmdDisassembler {
|
|||||||
is CmdGetIndex -> Opcode.GET_INDEX to intArrayOf(cmd.targetSlot, cmd.indexSlot, cmd.dst)
|
is CmdGetIndex -> Opcode.GET_INDEX to intArrayOf(cmd.targetSlot, cmd.indexSlot, cmd.dst)
|
||||||
is CmdSetIndex -> Opcode.SET_INDEX to intArrayOf(cmd.targetSlot, cmd.indexSlot, cmd.valueSlot)
|
is CmdSetIndex -> Opcode.SET_INDEX to intArrayOf(cmd.targetSlot, cmd.indexSlot, cmd.valueSlot)
|
||||||
is CmdListLiteral -> Opcode.LIST_LITERAL to intArrayOf(cmd.planId, cmd.baseSlot, cmd.count, cmd.dst)
|
is CmdListLiteral -> Opcode.LIST_LITERAL to intArrayOf(cmd.planId, cmd.baseSlot, cmd.count, cmd.dst)
|
||||||
|
is CmdGetThisMember -> Opcode.GET_THIS_MEMBER to intArrayOf(cmd.nameId, cmd.dst)
|
||||||
|
is CmdSetThisMember -> Opcode.SET_THIS_MEMBER to intArrayOf(cmd.nameId, cmd.valueSlot)
|
||||||
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)
|
||||||
@ -269,6 +271,10 @@ 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.GET_THIS_MEMBER ->
|
||||||
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
|
Opcode.SET_THIS_MEMBER ->
|
||||||
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
Opcode.EVAL_FALLBACK, Opcode.EVAL_REF, Opcode.EVAL_STMT, Opcode.EVAL_VALUE_FN ->
|
||||||
listOf(OperandKind.ID, OperandKind.SLOT)
|
listOf(OperandKind.ID, OperandKind.SLOT)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1252,6 +1252,42 @@ class CmdListLiteral(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CmdGetThisMember(
|
||||||
|
internal val nameId: Int,
|
||||||
|
internal val dst: Int,
|
||||||
|
) : Cmd() {
|
||||||
|
override suspend fun perform(frame: CmdFrame) {
|
||||||
|
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||||
|
frame.syncFrameToScope()
|
||||||
|
}
|
||||||
|
val nameConst = frame.fn.constants.getOrNull(nameId) as? BytecodeConst.StringVal
|
||||||
|
?: error("GET_THIS_MEMBER expects StringVal at $nameId")
|
||||||
|
val ref = net.sergeych.lyng.obj.ImplicitThisMemberRef(nameConst.value, frame.scope.pos)
|
||||||
|
val result = ref.evalValue(frame.scope)
|
||||||
|
frame.storeObjResult(dst, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmdSetThisMember(
|
||||||
|
internal val nameId: Int,
|
||||||
|
internal val valueSlot: Int,
|
||||||
|
) : Cmd() {
|
||||||
|
override suspend fun perform(frame: CmdFrame) {
|
||||||
|
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||||
|
frame.syncFrameToScope()
|
||||||
|
}
|
||||||
|
val nameConst = frame.fn.constants.getOrNull(nameId) as? BytecodeConst.StringVal
|
||||||
|
?: error("SET_THIS_MEMBER expects StringVal at $nameId")
|
||||||
|
val ref = net.sergeych.lyng.obj.ImplicitThisMemberRef(nameConst.value, frame.scope.pos)
|
||||||
|
ref.setAt(frame.scope.pos, frame.scope, frame.slotToObj(valueSlot))
|
||||||
|
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||||
|
frame.syncScopeToFrame()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CmdSetField(
|
class CmdSetField(
|
||||||
internal val recvSlot: Int,
|
internal val recvSlot: Int,
|
||||||
internal val fieldId: Int,
|
internal val fieldId: Int,
|
||||||
|
|||||||
@ -131,6 +131,8 @@ enum class Opcode(val code: Int) {
|
|||||||
SET_INDEX(0xA3),
|
SET_INDEX(0xA3),
|
||||||
GET_NAME(0xA4),
|
GET_NAME(0xA4),
|
||||||
LIST_LITERAL(0xA5),
|
LIST_LITERAL(0xA5),
|
||||||
|
GET_THIS_MEMBER(0xA6),
|
||||||
|
SET_THIS_MEMBER(0xA7),
|
||||||
|
|
||||||
EVAL_FALLBACK(0xB0),
|
EVAL_FALLBACK(0xB0),
|
||||||
RESOLVE_SCOPE_SLOT(0xB1),
|
RESOLVE_SCOPE_SLOT(0xB1),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user