Updated native lib with a couple of bugfixes (for Windows for now, others will be recompiled and updated after it's confirmed that the fixes actually work).

This commit is contained in:
Florian Nücke 2014-06-08 23:45:11 +02:00
parent ac811de85d
commit 12ae22eb30
3 changed files with 58 additions and 56 deletions

View File

@ -12,72 +12,74 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.pushString("__persist" + UUID.randomUUID().toString.replaceAll("-", "")) lua.pushString("__persist" + UUID.randomUUID().toString.replaceAll("-", ""))
lua.setGlobal("persistKey") lua.setGlobal("persistKey")
// These tables must contain all java callbacks (i.e. C functions, since if (Settings.get.allowPersistence) {
// they are wrapped on the native side using a C function, of course). // These tables must contain all java callbacks (i.e. C functions, since
// They are used when persisting/unpersisting the state so that the // they are wrapped on the native side using a C function, of course).
// persistence library knows which values it doesn't have to serialize // They are used when persisting/unpersisting the state so that the
// (since it cannot persist C functions). // persistence library knows which values it doesn't have to serialize
lua.newTable() /* ... perms */ // (since it cannot persist C functions).
lua.newTable() /* ... uperms */ lua.newTable() /* ... perms */
lua.newTable() /* ... uperms */
val perms = lua.getTop - 1 val perms = lua.getTop - 1
val uperms = lua.getTop val uperms = lua.getTop
def flattenAndStore() { def flattenAndStore() {
/* ... k v */ /* ... k v */
// We only care for tables and functions, any value types are safe. // We only care for tables and functions, any value types are safe.
if (lua.isFunction(-1) || lua.isTable(-1)) { if (lua.isFunction(-1) || lua.isTable(-1)) {
lua.pushValue(-2) /* ... k v k */
lua.getTable(uperms) /* ... k v uperms[k] */
assert(lua.isNil(-1), "duplicate permanent value named " + lua.toString(-3))
lua.pop(1) /* ... k v */
// If we have aliases its enough to store the value once.
lua.pushValue(-1) /* ... k v v */
lua.getTable(perms) /* ... k v perms[v] */
val isNew = lua.isNil(-1)
lua.pop(1) /* ... k v */
if (isNew) {
lua.pushValue(-1) /* ... k v v */
lua.pushValue(-3) /* ... k v v k */
lua.rawSet(perms) /* ... k v ; perms[v] = k */
lua.pushValue(-2) /* ... k v k */ lua.pushValue(-2) /* ... k v k */
lua.pushValue(-2) /* ... k v k v */ lua.getTable(uperms) /* ... k v uperms[k] */
lua.rawSet(uperms) /* ... k v ; uperms[k] = v */ assert(lua.isNil(-1), "duplicate permanent value named " + lua.toString(-3))
// Recurse into tables. lua.pop(1) /* ... k v */
if (lua.isTable(-1)) { // If we have aliases its enough to store the value once.
// Enforce a deterministic order when determining the keys, to ensure lua.pushValue(-1) /* ... k v v */
// the keys are the same when unpersisting again. lua.getTable(perms) /* ... k v perms[v] */
val key = lua.toString(-2) val isNew = lua.isNil(-1)
val childKeys = mutable.ArrayBuffer.empty[String] lua.pop(1) /* ... k v */
lua.pushNil() /* ... k v nil */ if (isNew) {
while (lua.next(-2)) { lua.pushValue(-1) /* ... k v v */
/* ... k v ck cv */ lua.pushValue(-3) /* ... k v v k */
lua.pop(1) /* ... k v ck */ lua.rawSet(perms) /* ... k v ; perms[v] = k */
childKeys += lua.toString(-1) lua.pushValue(-2) /* ... k v k */
} lua.pushValue(-2) /* ... k v k v */
/* ... k v */ lua.rawSet(uperms) /* ... k v ; uperms[k] = v */
childKeys.sortWith((a, b) => a.compareTo(b) < 0) // Recurse into tables.
for (childKey <- childKeys) { if (lua.isTable(-1)) {
lua.pushString(key + "." + childKey) /* ... k v ck */ // Enforce a deterministic order when determining the keys, to ensure
lua.getField(-2, childKey) /* ... k v ck cv */ // the keys are the same when unpersisting again.
flattenAndStore() /* ... k v */ val key = lua.toString(-2)
val childKeys = mutable.ArrayBuffer.empty[String]
lua.pushNil() /* ... k v nil */
while (lua.next(-2)) {
/* ... k v ck cv */
lua.pop(1) /* ... k v ck */
childKeys += lua.toString(-1)
}
/* ... k v */
childKeys.sortWith((a, b) => a.compareTo(b) < 0)
for (childKey <- childKeys) {
lua.pushString(key + "." + childKey) /* ... k v ck */
lua.getField(-2, childKey) /* ... k v ck cv */
flattenAndStore() /* ... k v */
}
/* ... k v */
} }
/* ... k v */ /* ... k v */
} }
/* ... k v */ /* ... k v */
} }
/* ... k v */ lua.pop(2) /* ... */
} }
lua.pop(2) /* ... */
// Mark everything that's globally reachable at this point as permanent.
lua.pushString("_G") /* ... perms uperms k */
lua.getGlobal("_G") /* ... perms uperms k v */
flattenAndStore() /* ... perms uperms */
lua.setField(LuaState.REGISTRYINDEX, "uperms") /* ... perms */
lua.setField(LuaState.REGISTRYINDEX, "perms") /* ... */
} }
// Mark everything that's globally reachable at this point as permanent.
lua.pushString("_G") /* ... perms uperms k */
lua.getGlobal("_G") /* ... perms uperms k v */
flattenAndStore() /* ... perms uperms */
lua.setField(LuaState.REGISTRYINDEX, "uperms") /* ... perms */
lua.setField(LuaState.REGISTRYINDEX, "perms") /* ... */
} }
def configure() { def configure() {