Fix module scope resolution in cmd runtime
This commit is contained in:
parent
9319add9c0
commit
89cf2c1612
@ -701,6 +701,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_EQ_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_EQ_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_EQ_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_EQ_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_EQ_INT, a.slot, b.slot, out)
|
||||||
@ -737,6 +743,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_NEQ_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_NEQ_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_NEQ_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_NEQ_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_NEQ_INT, a.slot, b.slot, out)
|
||||||
@ -773,6 +785,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_LT_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_LT_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_LT_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_LT_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_LT_INT, a.slot, b.slot, out)
|
||||||
@ -805,6 +823,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_LTE_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_LTE_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_LTE_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_LTE_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_LTE_INT, a.slot, b.slot, out)
|
||||||
@ -837,6 +861,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_GT_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_GT_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_GT_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_GT_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_GT_INT, a.slot, b.slot, out)
|
||||||
@ -869,6 +899,12 @@ class BytecodeCompiler(
|
|||||||
builder.emit(Opcode.CMP_GTE_OBJ, left.slot, right.slot, out)
|
builder.emit(Opcode.CMP_GTE_OBJ, left.slot, right.slot, out)
|
||||||
return CompiledValue(out, SlotType.BOOL)
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
}
|
}
|
||||||
|
if (a.type == SlotType.OBJ || b.type == SlotType.OBJ) {
|
||||||
|
val left = ensureObjSlot(a)
|
||||||
|
val right = ensureObjSlot(b)
|
||||||
|
builder.emit(Opcode.CMP_GTE_OBJ, left.slot, right.slot, out)
|
||||||
|
return CompiledValue(out, SlotType.BOOL)
|
||||||
|
}
|
||||||
return when {
|
return when {
|
||||||
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
a.type == SlotType.INT && b.type == SlotType.INT -> {
|
||||||
builder.emit(Opcode.CMP_GTE_INT, a.slot, b.slot, out)
|
builder.emit(Opcode.CMP_GTE_INT, a.slot, b.slot, out)
|
||||||
@ -2978,6 +3014,11 @@ class BytecodeCompiler(
|
|||||||
scopeSlotIndexByName[ref.name]?.let { return it }
|
scopeSlotIndexByName[ref.name]?.let { return it }
|
||||||
}
|
}
|
||||||
if (ref.captureOwnerScopeId != null) {
|
if (ref.captureOwnerScopeId != null) {
|
||||||
|
val ownerKey = ScopeSlotKey(ref.captureOwnerScopeId, ref.captureOwnerSlot ?: refSlot(ref))
|
||||||
|
val ownerLocal = localSlotIndexByKey[ownerKey]
|
||||||
|
if (ownerLocal != null) {
|
||||||
|
return scopeSlotCount + ownerLocal
|
||||||
|
}
|
||||||
val scopeKey = ScopeSlotKey(refScopeId(ref), refSlot(ref))
|
val scopeKey = ScopeSlotKey(refScopeId(ref), refSlot(ref))
|
||||||
return scopeSlotMap[scopeKey]
|
return scopeSlotMap[scopeKey]
|
||||||
}
|
}
|
||||||
@ -3530,7 +3571,17 @@ class BytecodeCompiler(
|
|||||||
if (stmt == null) return null
|
if (stmt == null) return null
|
||||||
val target = if (stmt is BytecodeStatement) stmt.original else stmt
|
val target = if (stmt is BytecodeStatement) stmt.original else stmt
|
||||||
val expr = target as? ExpressionStatement ?: return null
|
val expr = target as? ExpressionStatement ?: return null
|
||||||
return expr.ref as? RangeRef
|
val ref = expr.ref
|
||||||
|
if (ref is RangeRef) return ref
|
||||||
|
if (ref is ConstRef) {
|
||||||
|
val range = ref.constValue as? ObjRange ?: return null
|
||||||
|
val start = range.start as? ObjInt ?: return null
|
||||||
|
val end = range.end as? ObjInt ?: return null
|
||||||
|
val left = ConstRef(start.asReadonly)
|
||||||
|
val right = ConstRef(end.asReadonly)
|
||||||
|
return RangeRef(left, right, range.isEndInclusive)
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractRangeFromLocal(source: Statement): RangeRef? {
|
private fun extractRangeFromLocal(source: Statement): RangeRef? {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ package net.sergeych.lyng.bytecode
|
|||||||
|
|
||||||
import net.sergeych.lyng.Arguments
|
import net.sergeych.lyng.Arguments
|
||||||
import net.sergeych.lyng.ExecutionError
|
import net.sergeych.lyng.ExecutionError
|
||||||
|
import net.sergeych.lyng.ModuleScope
|
||||||
import net.sergeych.lyng.PerfFlags
|
import net.sergeych.lyng.PerfFlags
|
||||||
import net.sergeych.lyng.PerfStats
|
import net.sergeych.lyng.PerfStats
|
||||||
import net.sergeych.lyng.Pos
|
import net.sergeych.lyng.Pos
|
||||||
@ -1498,7 +1499,7 @@ class CmdFrame(
|
|||||||
|
|
||||||
var ip: Int = 0
|
var ip: Int = 0
|
||||||
var scope: Scope = scope0
|
var scope: Scope = scope0
|
||||||
private val moduleScope: Scope = scope0
|
private val moduleScope: Scope = resolveModuleScope(scope0)
|
||||||
val methodCallSites: MutableMap<Int, MethodCallSite> = CmdCallSiteCache.methodCallSites(fn)
|
val methodCallSites: MutableMap<Int, MethodCallSite> = CmdCallSiteCache.methodCallSites(fn)
|
||||||
|
|
||||||
internal val scopeStack = ArrayDeque<Scope>()
|
internal val scopeStack = ArrayDeque<Scope>()
|
||||||
@ -1521,6 +1522,18 @@ class CmdFrame(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resolveModuleScope(scope: Scope): Scope {
|
||||||
|
var current: Scope? = scope
|
||||||
|
var last: Scope = scope
|
||||||
|
while (current != null) {
|
||||||
|
if (current is ModuleScope) return current
|
||||||
|
if (current.parent is ModuleScope) return current
|
||||||
|
last = current
|
||||||
|
current = current.parent
|
||||||
|
}
|
||||||
|
return last
|
||||||
|
}
|
||||||
|
|
||||||
fun pushScope(plan: Map<String, Int>, captures: List<String>) {
|
fun pushScope(plan: Map<String, Int>, captures: List<String>) {
|
||||||
val parentScope = scope
|
val parentScope = scope
|
||||||
val captureRecords = if (captures.isNotEmpty()) {
|
val captureRecords = if (captures.isNotEmpty()) {
|
||||||
@ -1989,14 +2002,14 @@ class CmdFrame(
|
|||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
target.applySlotPlan(mapOf(name to index))
|
target.applySlotPlan(mapOf(name to index))
|
||||||
val existing = target.getLocalRecordDirect(name)
|
val existing = target.getLocalRecordDirect(name) ?: target.localBindings[name]
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
target.updateSlotFor(name, existing)
|
target.updateSlotFor(name, existing)
|
||||||
} else {
|
return index
|
||||||
val resolved = target.get(name)
|
}
|
||||||
if (resolved != null) {
|
val resolved = target.parent?.get(name) ?: target.get(name)
|
||||||
target.updateSlotFor(name, resolved)
|
if (resolved != null) {
|
||||||
}
|
target.updateSlotFor(name, resolved)
|
||||||
}
|
}
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1406,7 +1406,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenEndRanges3() = runTest {
|
fun testOpenEndRanges3() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -1419,7 +1418,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testCharacterRange() = runTest {
|
fun testCharacterRange() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -1434,7 +1432,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testIs() = runTest {
|
fun testIs() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -1450,7 +1447,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testForRange() = runTest {
|
fun testForRange() = runTest {
|
||||||
eval(
|
eval(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user