Avoid double-eval in optional compound assigns

This commit is contained in:
Sergey Chernov 2026-01-28 22:48:26 +03:00
parent 2c2468b672
commit ac5d1fa65a

View File

@ -975,8 +975,8 @@ class BytecodeCompiler(
if (nameId > 0xFFFF) return compileEvalRef(ref)
val current = allocSlot()
val result = allocSlot()
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
if (!fieldTarget.isOptional) {
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.GET_FIELD, receiver.slot, nameId, current)
builder.emit(objOp, current, rhs.slot, result)
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
@ -993,15 +993,13 @@ class BytecodeCompiler(
Opcode.JMP_IF_TRUE,
listOf(CmdBuilder.Operand.IntVal(cmpSlot), CmdBuilder.Operand.LabelRef(nullLabel))
)
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.GET_FIELD, receiver.slot, nameId, current)
builder.emit(objOp, current, rhs.slot, result)
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
builder.mark(nullLabel)
val rhsNull = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.CONST_NULL, current)
builder.emit(objOp, current, rhsNull.slot, result)
builder.emit(objOp, current, rhs.slot, result)
builder.mark(endLabel)
updateSlotType(result, SlotType.OBJ)
return CompiledValue(result, SlotType.OBJ)
@ -1024,9 +1022,9 @@ class BytecodeCompiler(
val receiver = compileRefWithFallback(indexTarget.targetRef, null, Pos.builtIn) ?: return null
val current = allocSlot()
val result = allocSlot()
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
if (!indexTarget.optionalRef) {
val index = compileRefWithFallback(indexTarget.indexRef, null, Pos.builtIn) ?: return null
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.GET_INDEX, receiver.slot, index.slot, current)
builder.emit(objOp, current, rhs.slot, result)
builder.emit(Opcode.SET_INDEX, receiver.slot, index.slot, result)
@ -1044,15 +1042,13 @@ class BytecodeCompiler(
listOf(CmdBuilder.Operand.IntVal(cmpSlot), CmdBuilder.Operand.LabelRef(nullLabel))
)
val index = compileRefWithFallback(indexTarget.indexRef, null, Pos.builtIn) ?: return null
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.GET_INDEX, receiver.slot, index.slot, current)
builder.emit(objOp, current, rhs.slot, result)
builder.emit(Opcode.SET_INDEX, receiver.slot, index.slot, result)
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
builder.mark(nullLabel)
val rhsNull = compileRef(ref.value) ?: return compileEvalRef(ref)
builder.emit(Opcode.CONST_NULL, current)
builder.emit(objOp, current, rhsNull.slot, result)
builder.emit(objOp, current, rhs.slot, result)
builder.mark(endLabel)
updateSlotType(result, SlotType.OBJ)
return CompiledValue(result, SlotType.OBJ)