- fixed CLI -x mode
- fixed a wrong error message when global symbol is not found
This commit is contained in:
1 parent
6e9333844e
commit
c097464750
13 files changed
+426
-77
No files matched your search
@@ -187,6 +187,8 @@ class Compiler(
|
||||
private val externCallableNames: MutableSet<String> = mutableSetOf()
|
||||
private val externBindingNames: MutableSet<String> = mutableSetOf()
|
||||
private val moduleDeclaredNames: MutableSet<String> = mutableSetOf()
|
||||
private val predeclaredTopLevelValueNames: MutableSet<String> = mutableSetOf()
|
||||
private val moduleReferencePosByName: MutableMap<String, Pos> = mutableMapOf()
|
||||
private var seedingSlotPlan: Boolean = false
|
||||
|
||||
private fun moduleForcedLocalSlotInfo(): Map<String, ForcedLocalSlotInfo> {
|
||||
@@ -393,6 +395,7 @@ class Compiler(
|
||||
}
|
||||
declareSlotNameIn(plan, nameToken.value, isMutable = t.value == "var", isDelegated = false)
|
||||
moduleDeclaredNames.add(nameToken.value)
|
||||
predeclaredTopLevelValueNames.add(nameToken.value)
|
||||
}
|
||||
"class", "object" -> {
|
||||
val nameToken = nextNonWs()
|
||||
@@ -933,6 +936,7 @@ class Compiler(
|
||||
}
|
||||
}
|
||||
captureLocalRef(name, slotLoc, pos)?.let { ref ->
|
||||
moduleReferencePosByName.putIfAbsent(name, pos)
|
||||
resolutionSink?.reference(name, pos)
|
||||
return ref
|
||||
}
|
||||
@@ -978,8 +982,11 @@ class Compiler(
|
||||
if (moduleLoc != null) {
|
||||
val moduleDeclaredNames = localNamesStack.firstOrNull()
|
||||
if (moduleDeclaredNames == null || !moduleDeclaredNames.contains(name)) {
|
||||
resolveImportBinding(name, pos)?.let { resolved ->
|
||||
registerImportBinding(name, resolved.binding, pos)
|
||||
val resolvedImport = resolveImportBinding(name, pos)
|
||||
if (resolvedImport != null) {
|
||||
registerImportBinding(name, resolvedImport.binding, pos)
|
||||
} else if (predeclaredTopLevelValueNames.contains(name)) {
|
||||
throw ScriptError(pos, "symbol '$name' is not defined")
|
||||
}
|
||||
}
|
||||
val ref = LocalSlotRef(
|
||||
@@ -1008,8 +1015,11 @@ class Compiler(
|
||||
if (moduleEntry != null) {
|
||||
val moduleDeclaredNames = localNamesStack.firstOrNull()
|
||||
if (moduleDeclaredNames == null || !moduleDeclaredNames.contains(name)) {
|
||||
resolveImportBinding(name, pos)?.let { resolved ->
|
||||
registerImportBinding(name, resolved.binding, pos)
|
||||
val resolvedImport = resolveImportBinding(name, pos)
|
||||
if (resolvedImport != null) {
|
||||
registerImportBinding(name, resolvedImport.binding, pos)
|
||||
} else if (predeclaredTopLevelValueNames.contains(name)) {
|
||||
throw ScriptError(pos, "symbol '$name' is not defined")
|
||||
}
|
||||
}
|
||||
val moduleLoc = SlotLocation(
|
||||
@@ -1020,6 +1030,7 @@ class Compiler(
|
||||
moduleEntry.isDelegated
|
||||
)
|
||||
captureLocalRef(name, moduleLoc, pos)?.let { ref ->
|
||||
moduleReferencePosByName.putIfAbsent(name, pos)
|
||||
resolutionSink?.reference(name, pos)
|
||||
return ref
|
||||
}
|
||||
@@ -1046,6 +1057,7 @@ class Compiler(
|
||||
strictSlotRefs
|
||||
)
|
||||
}
|
||||
moduleReferencePosByName.putIfAbsent(name, pos)
|
||||
resolutionSink?.reference(name, pos)
|
||||
return ref
|
||||
}
|
||||
@@ -1080,6 +1092,7 @@ class Compiler(
|
||||
val slot = lookupSlotLocation(name)
|
||||
if (slot != null) {
|
||||
captureLocalRef(name, slot, pos)?.let { ref ->
|
||||
moduleReferencePosByName.putIfAbsent(name, pos)
|
||||
resolutionSink?.reference(name, pos)
|
||||
return ref
|
||||
}
|
||||
@@ -1106,6 +1119,7 @@ class Compiler(
|
||||
strictSlotRefs
|
||||
)
|
||||
}
|
||||
moduleReferencePosByName.putIfAbsent(name, pos)
|
||||
resolutionSink?.reference(name, pos)
|
||||
return ref
|
||||
}
|
||||
@@ -1757,6 +1771,8 @@ class Compiler(
|
||||
callableReturnTypeByScopeId = callableReturnTypeByScopeId,
|
||||
callableReturnTypeByName = callableReturnTypeByName,
|
||||
externBindingNames = externBindingNames,
|
||||
preparedModuleBindingNames = importBindings.keys,
|
||||
scopeRefPosByName = moduleReferencePosByName,
|
||||
lambdaCaptureEntriesByRef = lambdaCaptureEntriesByRef
|
||||
) as BytecodeStatement
|
||||
unwrapped to bytecodeStmt.bytecodeFunction()
|
||||
@@ -2085,6 +2101,8 @@ class Compiler(
|
||||
callableReturnTypeByName = callableReturnTypeByName,
|
||||
externCallableNames = externCallableNames,
|
||||
externBindingNames = externBindingNames,
|
||||
preparedModuleBindingNames = importBindings.keys,
|
||||
scopeRefPosByName = moduleReferencePosByName,
|
||||
lambdaCaptureEntriesByRef = lambdaCaptureEntriesByRef
|
||||
)
|
||||
}
|
||||
@@ -2116,6 +2134,8 @@ class Compiler(
|
||||
callableReturnTypeByName = callableReturnTypeByName,
|
||||
externCallableNames = externCallableNames,
|
||||
externBindingNames = externBindingNames,
|
||||
preparedModuleBindingNames = importBindings.keys,
|
||||
scopeRefPosByName = moduleReferencePosByName,
|
||||
lambdaCaptureEntriesByRef = lambdaCaptureEntriesByRef
|
||||
)
|
||||
}
|
||||
@@ -2172,6 +2192,8 @@ class Compiler(
|
||||
callableReturnTypeByName = callableReturnTypeByName,
|
||||
externCallableNames = externCallableNames,
|
||||
externBindingNames = externBindingNames,
|
||||
preparedModuleBindingNames = importBindings.keys,
|
||||
scopeRefPosByName = moduleReferencePosByName,
|
||||
lambdaCaptureEntriesByRef = lambdaCaptureEntriesByRef
|
||||
)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ class BytecodeCompiler(
|
||||
private val callableReturnTypeByName: Map<String, ObjClass> = emptyMap(),
|
||||
private val externCallableNames: Set<String> = emptySet(),
|
||||
private val externBindingNames: Set<String> = emptySet(),
|
||||
private val preparedModuleBindingNames: Set<String> = emptySet(),
|
||||
private val scopeRefPosByName: Map<String, Pos> = emptyMap(),
|
||||
private val lambdaCaptureEntriesByRef: Map<ValueFnRef, List<LambdaCaptureEntry>> = emptyMap(),
|
||||
) {
|
||||
private val useScopeSlots: Boolean = allowedScopeNames != null || scopeSlotNameSet != null
|
||||
@@ -53,12 +55,15 @@ class BytecodeCompiler(
|
||||
private var scopeSlotIndices = IntArray(0)
|
||||
private var scopeSlotNames = emptyArray<String?>()
|
||||
private var scopeSlotIsModule = BooleanArray(0)
|
||||
private var scopeSlotRequiresPreparedBinding = BooleanArray(0)
|
||||
private var scopeSlotRefPos = emptyArray<Pos?>()
|
||||
private var scopeSlotMutables = BooleanArray(0)
|
||||
private var scopeKeyByIndex = emptyArray<ScopeSlotKey?>()
|
||||
private val scopeSlotMap = LinkedHashMap<ScopeSlotKey, Int>()
|
||||
private val scopeSlotNameMap = LinkedHashMap<ScopeSlotKey, String>()
|
||||
private val scopeSlotMutableMap = LinkedHashMap<ScopeSlotKey, Boolean>()
|
||||
private val scopeSlotIndexByName = LinkedHashMap<String, Int>()
|
||||
private val scopeSlotRefPosByKey = LinkedHashMap<ScopeSlotKey, Pos>()
|
||||
private val pendingScopeNameRefs = LinkedHashSet<String>()
|
||||
private val addrSlotByScopeSlot = LinkedHashMap<Int, Int>()
|
||||
private data class LocalSlotInfo(val name: String, val isMutable: Boolean, val isDelegated: Boolean)
|
||||
@@ -119,6 +124,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -140,6 +147,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -158,6 +167,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -176,6 +187,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -194,6 +207,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -212,6 +227,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -230,6 +247,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -248,6 +267,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -266,6 +287,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -284,6 +307,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -302,6 +327,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -322,6 +349,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -340,6 +369,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -358,6 +389,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -376,6 +409,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -395,6 +430,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -416,6 +453,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -439,6 +478,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -459,6 +500,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -534,6 +577,7 @@ class BytecodeCompiler(
|
||||
resolved = SlotType.INT
|
||||
}
|
||||
if (mapped < scopeSlotCount && resolved != SlotType.UNKNOWN) {
|
||||
noteScopeSlotRef(mapped, ref.pos())
|
||||
val addrSlot = ensureScopeAddr(mapped)
|
||||
val local = allocSlot()
|
||||
emitLoadFromAddr(addrSlot, local, resolved)
|
||||
@@ -544,6 +588,7 @@ class BytecodeCompiler(
|
||||
return CompiledValue(local, resolved)
|
||||
}
|
||||
if (mapped < scopeSlotCount && resolved == SlotType.UNKNOWN) {
|
||||
noteScopeSlotRef(mapped, ref.pos())
|
||||
val addrSlot = ensureScopeAddr(mapped)
|
||||
val local = allocSlot()
|
||||
emitLoadFromAddr(addrSlot, local, SlotType.OBJ)
|
||||
@@ -563,6 +608,7 @@ class BytecodeCompiler(
|
||||
}
|
||||
if (allowLocalSlots) {
|
||||
scopeSlotIndexByName[ref.name]?.let { slot ->
|
||||
noteScopeSlotRef(slot, callSitePos())
|
||||
val resolved = slotTypes[slot] ?: SlotType.UNKNOWN
|
||||
return CompiledValue(slot, resolved)
|
||||
}
|
||||
@@ -585,6 +631,7 @@ class BytecodeCompiler(
|
||||
return CompiledValue(slot, resolved)
|
||||
}
|
||||
scopeSlotIndexByName[ref.name]?.let { slot ->
|
||||
noteScopeSlotRef(slot, callSitePos())
|
||||
val resolved = slotTypes[slot] ?: SlotType.UNKNOWN
|
||||
return CompiledValue(slot, resolved)
|
||||
}
|
||||
@@ -596,6 +643,7 @@ class BytecodeCompiler(
|
||||
val slot = ref.slotIndex()
|
||||
val resolved = slotTypes[slot] ?: SlotType.UNKNOWN
|
||||
if (slot < scopeSlotCount && resolved != SlotType.UNKNOWN) {
|
||||
noteScopeSlotRef(slot, callSitePos())
|
||||
val addrSlot = ensureScopeAddr(slot)
|
||||
val local = allocSlot()
|
||||
emitLoadFromAddr(addrSlot, local, resolved)
|
||||
@@ -5002,6 +5050,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5021,6 +5071,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5041,6 +5093,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5061,6 +5115,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5084,6 +5140,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5103,6 +5161,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -5727,6 +5787,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices,
|
||||
scopeSlotNames,
|
||||
scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos,
|
||||
localSlotNames,
|
||||
localSlotMutables,
|
||||
localSlotDelegated,
|
||||
@@ -7599,6 +7661,12 @@ class BytecodeCompiler(
|
||||
private fun assignValue(ref: AssignRef): ObjRef = ref.value
|
||||
private fun refPos(ref: BinaryOpRef): Pos = Pos.builtIn
|
||||
|
||||
private fun noteScopeSlotRef(slot: Int, pos: Pos) {
|
||||
if (slot >= scopeSlotCount) return
|
||||
val key = scopeKeyByIndex.getOrNull(slot) ?: return
|
||||
scopeSlotRefPosByKey.putIfAbsent(key, pos)
|
||||
}
|
||||
|
||||
private fun resolveSlot(ref: LocalSlotRef): Int? {
|
||||
loopSlotOverrides[ref.name]?.let { return it }
|
||||
val scopeId = refScopeId(ref)
|
||||
@@ -7606,8 +7674,14 @@ class BytecodeCompiler(
|
||||
val key = ScopeSlotKey(scopeId, refSlot(ref))
|
||||
val localIndex = localSlotIndexByKey[key]
|
||||
if (localIndex != null) return scopeSlotCount + localIndex
|
||||
scopeSlotMap[key]?.let { return it }
|
||||
scopeSlotIndexByName[ref.name]?.let { return it }
|
||||
scopeSlotMap[key]?.let {
|
||||
scopeSlotRefPosByKey.putIfAbsent(key, ref.pos())
|
||||
return it
|
||||
}
|
||||
scopeSlotIndexByName[ref.name]?.let {
|
||||
scopeSlotRefPosByKey.putIfAbsent(key, ref.pos())
|
||||
return it
|
||||
}
|
||||
}
|
||||
if (ref.captureOwnerScopeId != null) {
|
||||
val scopeKey = ScopeSlotKey(refScopeId(ref), refSlot(ref))
|
||||
@@ -7617,7 +7691,11 @@ class BytecodeCompiler(
|
||||
return scopeSlotCount + localIndex
|
||||
}
|
||||
}
|
||||
return scopeSlotMap[scopeKey]
|
||||
val resolved = scopeSlotMap[scopeKey]
|
||||
if (resolved != null) {
|
||||
scopeSlotRefPosByKey.putIfAbsent(scopeKey, ref.pos())
|
||||
}
|
||||
return resolved
|
||||
}
|
||||
if (ref.isDelegated) {
|
||||
val localKey = ScopeSlotKey(refScopeId(ref), refSlot(ref))
|
||||
@@ -7628,7 +7706,11 @@ class BytecodeCompiler(
|
||||
val localIndex = localSlotIndexByKey[localKey]
|
||||
if (localIndex != null) return scopeSlotCount + localIndex
|
||||
val scopeKey = ScopeSlotKey(refScopeId(ref), refSlot(ref))
|
||||
return scopeSlotMap[scopeKey]
|
||||
val resolved = scopeSlotMap[scopeKey]
|
||||
if (resolved != null) {
|
||||
scopeSlotRefPosByKey.putIfAbsent(scopeKey, ref.pos())
|
||||
}
|
||||
return resolved
|
||||
}
|
||||
|
||||
private fun resolveCapturedOwnerScopeSlot(ref: LocalSlotRef): Int? {
|
||||
@@ -7858,6 +7940,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices = IntArray(scopeSlotCount)
|
||||
scopeSlotNames = arrayOfNulls(scopeSlotCount)
|
||||
scopeSlotIsModule = BooleanArray(scopeSlotCount)
|
||||
scopeSlotRequiresPreparedBinding = BooleanArray(scopeSlotCount)
|
||||
scopeSlotRefPos = arrayOfNulls(scopeSlotCount)
|
||||
scopeSlotMutables = BooleanArray(scopeSlotCount) { true }
|
||||
scopeKeyByIndex = arrayOfNulls(scopeSlotCount)
|
||||
for ((key, index) in scopeSlotMap) {
|
||||
@@ -7865,6 +7949,8 @@ class BytecodeCompiler(
|
||||
scopeSlotIndices[index] = key.slot
|
||||
scopeSlotNames[index] = name
|
||||
scopeSlotIsModule[index] = moduleScopeId != null && key.scopeId == moduleScopeId
|
||||
scopeSlotRequiresPreparedBinding[index] = name != null && preparedModuleBindingNames.contains(name)
|
||||
scopeSlotRefPos[index] = name?.let { scopeRefPosByName[it] } ?: scopeSlotRefPosByKey[key]
|
||||
scopeSlotMutableMap[key]?.let { scopeSlotMutables[index] = it }
|
||||
scopeKeyByIndex[index] = key
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ class BytecodeStatement private constructor(
|
||||
callableReturnTypeByName: Map<String, ObjClass> = emptyMap(),
|
||||
externCallableNames: Set<String> = emptySet(),
|
||||
externBindingNames: Set<String> = emptySet(),
|
||||
preparedModuleBindingNames: Set<String> = emptySet(),
|
||||
scopeRefPosByName: Map<String, Pos> = emptyMap(),
|
||||
lambdaCaptureEntriesByRef: Map<ValueFnRef, List<LambdaCaptureEntry>> = emptyMap(),
|
||||
slotTypeDeclByScopeId: Map<Int, Map<Int, TypeDecl>> = emptyMap(),
|
||||
): Statement {
|
||||
@@ -124,6 +126,8 @@ class BytecodeStatement private constructor(
|
||||
callableReturnTypeByName = callableReturnTypeByName,
|
||||
externCallableNames = externCallableNames,
|
||||
externBindingNames = externBindingNames,
|
||||
preparedModuleBindingNames = preparedModuleBindingNames,
|
||||
scopeRefPosByName = scopeRefPosByName,
|
||||
lambdaCaptureEntriesByRef = lambdaCaptureEntriesByRef
|
||||
)
|
||||
val compiled = compiler.compileStatement(nameHint, statement)
|
||||
|
||||
@@ -67,6 +67,8 @@ class CmdBuilder {
|
||||
scopeSlotIndices: IntArray = IntArray(0),
|
||||
scopeSlotNames: Array<String?> = emptyArray(),
|
||||
scopeSlotIsModule: BooleanArray = BooleanArray(0),
|
||||
scopeSlotRequiresPreparedBinding: BooleanArray = BooleanArray(0),
|
||||
scopeSlotRefPos: Array<net.sergeych.lyng.Pos?> = emptyArray(),
|
||||
localSlotNames: Array<String?> = emptyArray(),
|
||||
localSlotMutables: BooleanArray = BooleanArray(0),
|
||||
localSlotDelegated: BooleanArray = BooleanArray(0),
|
||||
@@ -79,6 +81,12 @@ class CmdBuilder {
|
||||
require(scopeSlotIsModule.isEmpty() || scopeSlotIsModule.size == scopeSlotCount) {
|
||||
"scope slot module mapping size mismatch"
|
||||
}
|
||||
require(scopeSlotRequiresPreparedBinding.isEmpty() || scopeSlotRequiresPreparedBinding.size == scopeSlotCount) {
|
||||
"scope slot prepared-binding mapping size mismatch"
|
||||
}
|
||||
require(scopeSlotRefPos.isEmpty() || scopeSlotRefPos.size == scopeSlotCount) {
|
||||
"scope slot position mapping size mismatch"
|
||||
}
|
||||
require(localSlotNames.size == localSlotMutables.size) { "local slot metadata size mismatch" }
|
||||
require(localSlotNames.size == localSlotDelegated.size) { "local slot delegation size mismatch" }
|
||||
require(localSlotNames.size == localSlotCaptures.size) { "local slot capture size mismatch" }
|
||||
@@ -113,6 +121,8 @@ class CmdBuilder {
|
||||
scopeSlotIndices = scopeSlotIndices,
|
||||
scopeSlotNames = if (scopeSlotNames.isEmpty()) Array(scopeSlotCount) { null } else scopeSlotNames,
|
||||
scopeSlotIsModule = if (scopeSlotIsModule.isEmpty()) BooleanArray(scopeSlotCount) else scopeSlotIsModule,
|
||||
scopeSlotRequiresPreparedBinding = if (scopeSlotRequiresPreparedBinding.isEmpty()) BooleanArray(scopeSlotCount) else scopeSlotRequiresPreparedBinding,
|
||||
scopeSlotRefPos = if (scopeSlotRefPos.isEmpty()) Array(scopeSlotCount) { null } else scopeSlotRefPos,
|
||||
localSlotNames = localSlotNames,
|
||||
localSlotMutables = localSlotMutables,
|
||||
localSlotDelegated = localSlotDelegated,
|
||||
|
||||
@@ -26,6 +26,8 @@ data class CmdFunction(
|
||||
val scopeSlotIndices: IntArray,
|
||||
val scopeSlotNames: Array<String?>,
|
||||
val scopeSlotIsModule: BooleanArray,
|
||||
val scopeSlotRequiresPreparedBinding: BooleanArray,
|
||||
val scopeSlotRefPos: Array<net.sergeych.lyng.Pos?>,
|
||||
val localSlotNames: Array<String?>,
|
||||
val localSlotMutables: BooleanArray,
|
||||
val localSlotDelegated: BooleanArray,
|
||||
@@ -38,6 +40,8 @@ data class CmdFunction(
|
||||
require(scopeSlotIndices.size == scopeSlotCount) { "scopeSlotIndices size mismatch" }
|
||||
require(scopeSlotNames.size == scopeSlotCount) { "scopeSlotNames size mismatch" }
|
||||
require(scopeSlotIsModule.size == scopeSlotCount) { "scopeSlotIsModule size mismatch" }
|
||||
require(scopeSlotRequiresPreparedBinding.size == scopeSlotCount) { "scopeSlotRequiresPreparedBinding size mismatch" }
|
||||
require(scopeSlotRefPos.size == scopeSlotCount) { "scopeSlotRefPos size mismatch" }
|
||||
require(localSlotNames.size == localSlotMutables.size) { "localSlot metadata size mismatch" }
|
||||
require(localSlotNames.size == localSlotDelegated.size) { "localSlot delegation size mismatch" }
|
||||
require(localSlotNames.size == localSlotCaptures.size) { "localSlot capture size mismatch" }
|
||||
|
||||
@@ -4112,7 +4112,7 @@ class CmdFrame(
|
||||
}
|
||||
|
||||
fun ensureScope(): Scope {
|
||||
val pos = posForIp(ip - 1)
|
||||
val pos = currentErrorPos()
|
||||
if (pos != null && lastScopePosIp != ip) {
|
||||
scope.pos = pos
|
||||
lastScopePosIp = ip
|
||||
@@ -4189,6 +4189,33 @@ class CmdFrame(
|
||||
return fn.posByIp.getOrNull(ip)
|
||||
}
|
||||
|
||||
private fun currentErrorPos(): Pos? {
|
||||
val center = ip - 1
|
||||
if (center < 0) return null
|
||||
var fallback: Pos? = null
|
||||
val maxRadius = maxOf(center, fn.posByIp.size - 1 - center)
|
||||
for (radius in 0..maxRadius) {
|
||||
val before = center - radius
|
||||
if (before >= 0) {
|
||||
val pos = posForIp(before)
|
||||
if (pos != null) {
|
||||
if (pos.source !== Source.builtIn && pos.source !== Source.UNKNOWN) return pos
|
||||
if (fallback == null) fallback = pos
|
||||
}
|
||||
}
|
||||
if (radius == 0) continue
|
||||
val after = center + radius
|
||||
if (after < fn.posByIp.size) {
|
||||
val pos = posForIp(after)
|
||||
if (pos != null) {
|
||||
if (pos.source !== Source.builtIn && pos.source !== Source.UNKNOWN) return pos
|
||||
if (fallback == null) fallback = pos
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
fun pushScope(plan: Map<String, Int>, captures: List<String>) {
|
||||
if (scope.skipScopeCreation) {
|
||||
val snapshot = emptyMap<String, Int?>()
|
||||
@@ -5045,8 +5072,12 @@ class CmdFrame(
|
||||
if (hadNamedBinding) return
|
||||
if (record.value !== ObjUnset) return
|
||||
if (fn.scopeSlotIsModule.getOrNull(slot) != true) return
|
||||
val pos = fn.scopeSlotRefPos.getOrNull(slot) ?: currentErrorPos() ?: ensureScope().pos
|
||||
if (fn.scopeSlotRequiresPreparedBinding.getOrNull(slot) != true) {
|
||||
throw ScriptError(pos, "symbol '$name' is not defined")
|
||||
}
|
||||
throw ScriptError(
|
||||
ensureScope().pos,
|
||||
pos,
|
||||
"module binding '$name' is not available in the execution scope; prepare the script imports/module bindings explicitly"
|
||||
)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user