Avoid double-eval in optional compound assigns
This commit is contained in:
parent
2c2468b672
commit
ac5d1fa65a
@ -975,8 +975,8 @@ class BytecodeCompiler(
|
|||||||
if (nameId > 0xFFFF) return compileEvalRef(ref)
|
if (nameId > 0xFFFF) return compileEvalRef(ref)
|
||||||
val current = allocSlot()
|
val current = allocSlot()
|
||||||
val result = allocSlot()
|
val result = allocSlot()
|
||||||
|
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
|
||||||
if (!fieldTarget.isOptional) {
|
if (!fieldTarget.isOptional) {
|
||||||
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
|
|
||||||
builder.emit(Opcode.GET_FIELD, receiver.slot, nameId, current)
|
builder.emit(Opcode.GET_FIELD, receiver.slot, nameId, current)
|
||||||
builder.emit(objOp, current, rhs.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
||||||
@ -993,15 +993,13 @@ class BytecodeCompiler(
|
|||||||
Opcode.JMP_IF_TRUE,
|
Opcode.JMP_IF_TRUE,
|
||||||
listOf(CmdBuilder.Operand.IntVal(cmpSlot), CmdBuilder.Operand.LabelRef(nullLabel))
|
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(Opcode.GET_FIELD, receiver.slot, nameId, current)
|
||||||
builder.emit(objOp, current, rhs.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
||||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
|
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
|
||||||
builder.mark(nullLabel)
|
builder.mark(nullLabel)
|
||||||
val rhsNull = compileRef(ref.value) ?: return compileEvalRef(ref)
|
|
||||||
builder.emit(Opcode.CONST_NULL, current)
|
builder.emit(Opcode.CONST_NULL, current)
|
||||||
builder.emit(objOp, current, rhsNull.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.mark(endLabel)
|
builder.mark(endLabel)
|
||||||
updateSlotType(result, SlotType.OBJ)
|
updateSlotType(result, SlotType.OBJ)
|
||||||
return CompiledValue(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 receiver = compileRefWithFallback(indexTarget.targetRef, null, Pos.builtIn) ?: return null
|
||||||
val current = allocSlot()
|
val current = allocSlot()
|
||||||
val result = allocSlot()
|
val result = allocSlot()
|
||||||
|
val rhs = compileRef(ref.value) ?: return compileEvalRef(ref)
|
||||||
if (!indexTarget.optionalRef) {
|
if (!indexTarget.optionalRef) {
|
||||||
val index = compileRefWithFallback(indexTarget.indexRef, null, Pos.builtIn) ?: return null
|
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(Opcode.GET_INDEX, receiver.slot, index.slot, current)
|
||||||
builder.emit(objOp, current, rhs.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.emit(Opcode.SET_INDEX, receiver.slot, index.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))
|
listOf(CmdBuilder.Operand.IntVal(cmpSlot), CmdBuilder.Operand.LabelRef(nullLabel))
|
||||||
)
|
)
|
||||||
val index = compileRefWithFallback(indexTarget.indexRef, null, Pos.builtIn) ?: return null
|
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(Opcode.GET_INDEX, receiver.slot, index.slot, current)
|
||||||
builder.emit(objOp, current, rhs.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.emit(Opcode.SET_INDEX, receiver.slot, index.slot, result)
|
builder.emit(Opcode.SET_INDEX, receiver.slot, index.slot, result)
|
||||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
|
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
|
||||||
builder.mark(nullLabel)
|
builder.mark(nullLabel)
|
||||||
val rhsNull = compileRef(ref.value) ?: return compileEvalRef(ref)
|
|
||||||
builder.emit(Opcode.CONST_NULL, current)
|
builder.emit(Opcode.CONST_NULL, current)
|
||||||
builder.emit(objOp, current, rhsNull.slot, result)
|
builder.emit(objOp, current, rhs.slot, result)
|
||||||
builder.mark(endLabel)
|
builder.mark(endLabel)
|
||||||
updateSlotType(result, SlotType.OBJ)
|
updateSlotType(result, SlotType.OBJ)
|
||||||
return CompiledValue(result, SlotType.OBJ)
|
return CompiledValue(result, SlotType.OBJ)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user