Fix bytecode bool conversion and object equality
This commit is contained in:
1 parent
7b3d92beb9
commit
63bcb91504
6 files changed
+197
-81
No files matched your search
@@ -1182,9 +1182,6 @@ class BytecodeCompiler(
|
||||
}
|
||||
|
||||
private fun compileCall(ref: CallRef): CompiledValue? {
|
||||
if (ref.target is LocalVarRef || ref.target is FastLocalVarRef || ref.target is BoundLocalVarRef) {
|
||||
return null
|
||||
}
|
||||
val fieldTarget = ref.target as? FieldRef
|
||||
if (fieldTarget != null) {
|
||||
val receiver = compileRefWithFallback(fieldTarget.target, null, Pos.builtIn) ?: return null
|
||||
@@ -1195,7 +1192,7 @@ class BytecodeCompiler(
|
||||
val args = compileCallArgs(ref.args, ref.tailBlock) ?: return null
|
||||
val encodedCount = encodeCallArgCount(args) ?: return null
|
||||
builder.emit(Opcode.CALL_VIRTUAL, receiver.slot, methodId, args.base, encodedCount, dst)
|
||||
return CompiledValue(dst, SlotType.UNKNOWN)
|
||||
return CompiledValue(dst, SlotType.OBJ)
|
||||
}
|
||||
val nullSlot = allocSlot()
|
||||
builder.emit(Opcode.CONST_NULL, nullSlot)
|
||||
@@ -1222,7 +1219,7 @@ class BytecodeCompiler(
|
||||
val args = compileCallArgs(ref.args, ref.tailBlock) ?: return null
|
||||
val encodedCount = encodeCallArgCount(args) ?: return null
|
||||
builder.emit(Opcode.CALL_SLOT, callee.slot, args.base, encodedCount, dst)
|
||||
return CompiledValue(dst, SlotType.UNKNOWN)
|
||||
return CompiledValue(dst, SlotType.OBJ)
|
||||
}
|
||||
val nullSlot = allocSlot()
|
||||
builder.emit(Opcode.CONST_NULL, nullSlot)
|
||||
@@ -1253,7 +1250,7 @@ class BytecodeCompiler(
|
||||
val args = compileCallArgs(ref.args, ref.tailBlock) ?: return null
|
||||
val encodedCount = encodeCallArgCount(args) ?: return null
|
||||
builder.emit(Opcode.CALL_VIRTUAL, receiver.slot, methodId, args.base, encodedCount, dst)
|
||||
return CompiledValue(dst, SlotType.UNKNOWN)
|
||||
return CompiledValue(dst, SlotType.OBJ)
|
||||
}
|
||||
val nullSlot = allocSlot()
|
||||
builder.emit(Opcode.CONST_NULL, nullSlot)
|
||||
@@ -2186,6 +2183,24 @@ class BytecodeCompiler(
|
||||
if (compiled != null) {
|
||||
if (forceType == null) return compiled
|
||||
if (compiled.type == forceType) return compiled
|
||||
if (forceType == SlotType.BOOL) {
|
||||
val converted = when (compiled.type) {
|
||||
SlotType.INT -> {
|
||||
val dst = allocSlot()
|
||||
builder.emit(Opcode.INT_TO_BOOL, compiled.slot, dst)
|
||||
updateSlotType(dst, SlotType.BOOL)
|
||||
CompiledValue(dst, SlotType.BOOL)
|
||||
}
|
||||
SlotType.OBJ -> {
|
||||
val dst = allocSlot()
|
||||
builder.emit(Opcode.OBJ_TO_BOOL, compiled.slot, dst)
|
||||
updateSlotType(dst, SlotType.BOOL)
|
||||
CompiledValue(dst, SlotType.BOOL)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
if (converted != null) return converted
|
||||
}
|
||||
if (compiled.type == SlotType.UNKNOWN) {
|
||||
compiled = null
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.sergeych.lyng.PerfStats
|
||||
import net.sergeych.lyng.Pos
|
||||
import net.sergeych.lyng.ReturnException
|
||||
import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.Statement
|
||||
import net.sergeych.lyng.obj.*
|
||||
|
||||
class CmdVm {
|
||||
@@ -713,14 +714,18 @@ class CmdCmpNeqRealInt(internal val a: Int, internal val b: Int, internal val ds
|
||||
|
||||
class CmdCmpEqObj(internal val a: Int, internal val b: Int, internal val dst: Int) : Cmd() {
|
||||
override suspend fun perform(frame: CmdFrame) {
|
||||
frame.setBool(dst, frame.slotToObj(a) == frame.slotToObj(b))
|
||||
val left = frame.slotToObj(a)
|
||||
val right = frame.slotToObj(b)
|
||||
frame.setBool(dst, left.equals(frame.scope, right))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
class CmdCmpNeqObj(internal val a: Int, internal val b: Int, internal val dst: Int) : Cmd() {
|
||||
override suspend fun perform(frame: CmdFrame) {
|
||||
frame.setBool(dst, frame.slotToObj(a) != frame.slotToObj(b))
|
||||
val left = frame.slotToObj(a)
|
||||
val right = frame.slotToObj(b)
|
||||
frame.setBool(dst, !left.equals(frame.scope, right))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1109,9 +1114,11 @@ class CmdCallSlot(
|
||||
}
|
||||
val callee = frame.slotToObj(calleeSlot)
|
||||
val args = frame.buildArguments(argBase, argCount)
|
||||
val result = if (PerfFlags.SCOPE_POOL) {
|
||||
val canPool = PerfFlags.SCOPE_POOL && callee !is Statement
|
||||
val result = if (canPool) {
|
||||
frame.scope.withChildFrame(args) { child -> callee.callOn(child) }
|
||||
} else {
|
||||
// Pooling for Statement-based callables (lambdas) can still alter closure semantics; keep safe path for now.
|
||||
callee.callOn(frame.scope.createChildScope(frame.scope.pos, args = args))
|
||||
}
|
||||
if (frame.fn.localSlotNames.isNotEmpty()) {
|
||||
|
||||
@@ -1588,15 +1588,16 @@ class CallRef(
|
||||
internal val isOptionalInvoke: Boolean,
|
||||
) : ObjRef {
|
||||
override suspend fun get(scope: Scope): ObjRecord {
|
||||
val usePool = PerfFlags.SCOPE_POOL
|
||||
val callee = target.evalValue(scope)
|
||||
if (callee == ObjNull && isOptionalInvoke) return ObjNull.asReadonly
|
||||
val callArgs = args.toArguments(scope, tailBlock)
|
||||
val usePool = PerfFlags.SCOPE_POOL && callee !is Statement
|
||||
val result: Obj = if (usePool) {
|
||||
scope.withChildFrame(callArgs) { child ->
|
||||
callee.callOn(child)
|
||||
}
|
||||
} else {
|
||||
// Pooling for Statement callables (lambdas) can still perturb closure semantics; keep safe path for now.
|
||||
callee.callOn(scope.createChildScope(scope.pos, callArgs))
|
||||
}
|
||||
return result.asReadonly
|
||||
|
||||
Reference in new issue
Block a user