Bytecode compile in/not in via contains
This commit is contained in:
parent
63bcb91504
commit
250220a42f
@ -204,6 +204,29 @@ class BytecodeCompiler(
|
||||
if (op == BinOp.AND || op == BinOp.OR) {
|
||||
return compileLogical(op, binaryLeft(ref), binaryRight(ref), refPos(ref))
|
||||
}
|
||||
if (op == BinOp.IN || op == BinOp.NOTIN) {
|
||||
val leftValue = compileRefWithFallback(binaryLeft(ref), null, refPos(ref)) ?: return null
|
||||
val rightValue = compileRefWithFallback(binaryRight(ref), null, refPos(ref)) ?: return null
|
||||
val leftObj = ensureObjSlot(leftValue)
|
||||
val rightObj = ensureObjSlot(rightValue)
|
||||
val methodId = builder.addConst(BytecodeConst.StringVal("contains"))
|
||||
if (methodId > 0xFFFF) return null
|
||||
val argSlot = allocSlot()
|
||||
builder.emit(Opcode.BOX_OBJ, leftObj.slot, argSlot)
|
||||
updateSlotType(argSlot, SlotType.OBJ)
|
||||
val callSlot = allocSlot()
|
||||
builder.emit(Opcode.CALL_VIRTUAL, rightObj.slot, methodId, argSlot, 1, callSlot)
|
||||
val boolSlot = allocSlot()
|
||||
builder.emit(Opcode.OBJ_TO_BOOL, callSlot, boolSlot)
|
||||
updateSlotType(boolSlot, SlotType.BOOL)
|
||||
if (op == BinOp.NOTIN) {
|
||||
val outSlot = allocSlot()
|
||||
builder.emit(Opcode.NOT_BOOL, boolSlot, outSlot)
|
||||
updateSlotType(outSlot, SlotType.BOOL)
|
||||
return CompiledValue(outSlot, SlotType.BOOL)
|
||||
}
|
||||
return CompiledValue(boolSlot, SlotType.BOOL)
|
||||
}
|
||||
val leftRef = binaryLeft(ref)
|
||||
val rightRef = binaryRight(ref)
|
||||
var a = compileRef(leftRef) ?: return null
|
||||
|
||||
@ -5201,6 +5201,20 @@ class ScriptTest {
|
||||
assertEquals(ObjInt(2), scope.eval("firstEvenOrMinus()"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInOperatorBytecode() = runTest {
|
||||
val scope = Script.newScope()
|
||||
scope.eval(
|
||||
"""
|
||||
fun inList(x, xs) { x in xs }
|
||||
""".trimIndent()
|
||||
)
|
||||
val disasm = scope.disassembleSymbol("inList")
|
||||
assertFalse(disasm.contains("not a compiled body"))
|
||||
assertEquals(ObjTrue, scope.eval("inList(2, [1,2,3])"))
|
||||
assertEquals(ObjFalse, scope.eval("inList(5, [1,2,3])"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilterBug() = runTest {
|
||||
eval(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user