fix #74 duplicate constructor amd state vars with Lynon serialization
This commit is contained in:
parent
603023962e
commit
0c31ec63ee
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "1.0.5-SNAPSHOT"
|
||||
version = "1.0.6-SNAPSHOT"
|
||||
|
||||
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
||||
|
||||
|
||||
@ -210,8 +210,13 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
|
||||
// using objlist allow for some optimizations:
|
||||
val params = meta.params.map { readField(scope, it.name).value }
|
||||
println("serializing $objClass with params: $params")
|
||||
encoder.encodeAnyList(scope, params)
|
||||
serializeStateVars(scope, encoder)
|
||||
val vars = serializingVars.values.map { it.value }
|
||||
println("encoding vars: $vars")
|
||||
if (vars.isNotEmpty<Obj>()) {
|
||||
encoder.encodeAnyList(scope, vars)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun toJson(scope: Scope): JsonElement {
|
||||
@ -232,9 +237,9 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
return JsonObject(result)
|
||||
}
|
||||
|
||||
val instanceVars: Map<String, ObjRecord> by lazy {
|
||||
instanceScope.objects.filter { it.value.type.serializable }
|
||||
}
|
||||
// val instanceVars: Map<String, ObjRecord> by lazy {
|
||||
// instanceScope.objects.filter { it.value.type.serializable }
|
||||
// }
|
||||
|
||||
val serializingVars: Map<String, ObjRecord> by lazy {
|
||||
instanceScope.objects.filter {
|
||||
@ -243,18 +248,11 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
it.value.isMutable }
|
||||
}
|
||||
|
||||
protected suspend fun serializeStateVars(scope: Scope, encoder: LynonEncoder) {
|
||||
val vars = instanceVars.values.map { it.value }
|
||||
if (vars.isNotEmpty()) {
|
||||
encoder.encodeAnyList(scope, vars)
|
||||
}
|
||||
}
|
||||
|
||||
internal suspend fun deserializeStateVars(scope: Scope, decoder: LynonDecoder) {
|
||||
val localVars = instanceVars.values.toList()
|
||||
val localVars = serializingVars.values.toList()
|
||||
if (localVars.isNotEmpty()) {
|
||||
val vars = decoder.decodeAnyList(scope)
|
||||
if (vars.size > instanceVars.size)
|
||||
if (vars.size > serializingVars.size)
|
||||
scope.raiseIllegalArgument("serialized vars has bigger size than instance vars")
|
||||
for ((i, v) in vars.withIndex()) {
|
||||
localVars[i].value = v
|
||||
|
||||
@ -3815,20 +3815,43 @@ class ScriptTest {
|
||||
assertEquals(JSTest1("bar", 1, true), x.decodeSerializable<JSTest1>())
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun testInstanceVars() = runTest {
|
||||
// val x = eval("""
|
||||
// class T(x,y)
|
||||
// T(1, 2)
|
||||
// """.trimIndent()) as ObjInstance
|
||||
// println(x.serializingVars.map { "${it.key}=${it.value.value}"})
|
||||
// }
|
||||
@Test
|
||||
fun testInstanceVars() = runTest {
|
||||
var x = eval("""
|
||||
// in this case, x and y are constructor parameters, not instance variables:
|
||||
class T(x,y) {
|
||||
// and z is val and therefore needn't serialization either:
|
||||
val z = x + y
|
||||
}
|
||||
T(1, 2)
|
||||
""".trimIndent()) as ObjInstance
|
||||
println(x.serializingVars.map { "${it.key}=${it.value.value}"})
|
||||
// so serializingVars is empty:
|
||||
assertEquals(emptyMap(), x.serializingVars)
|
||||
|
||||
x = eval("""
|
||||
class T(x,y) {
|
||||
// variable z though should be serialized:
|
||||
var z = x + y
|
||||
}
|
||||
val x = T(1, 2)
|
||||
x.z = 100
|
||||
assertEquals(100, x.z)
|
||||
x
|
||||
""".trimIndent()) as ObjInstance
|
||||
// z is instance var, it must present
|
||||
val z = x.serializingVars["z"] ?: x.serializingVars["T::z"]
|
||||
// and be mutable:
|
||||
assertTrue( z!!.isMutable )
|
||||
println(x.serializingVars.map { "${it.key}=${it.value.value}"})
|
||||
}
|
||||
|
||||
@Test
|
||||
fun memberValCantBeAssigned() = runTest {
|
||||
eval("""
|
||||
class Point(foo,bar) {
|
||||
val t = 42
|
||||
var r = 142
|
||||
}
|
||||
val p = Point(1,2)
|
||||
// val should not be assignable:
|
||||
@ -3837,8 +3860,13 @@ class ScriptTest {
|
||||
// val field must be readonly:
|
||||
assertThrows { p.t = "bad" }
|
||||
|
||||
p.r = 123
|
||||
|
||||
// and the value should not be changed
|
||||
assertEqual(42, p.t)
|
||||
|
||||
// but r should be changed:
|
||||
assertEqual(123, p.r)
|
||||
""")
|
||||
}
|
||||
|
||||
|
||||
@ -723,6 +723,61 @@ class Wallet( id, ownerKey, balance=0, createdAt=Instant.now().truncateToSecond(
|
||||
assertEquals(cp, cp2)
|
||||
""")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testClassSerializationSizes() = runTest {
|
||||
testScope().eval("""
|
||||
class Point(x=0,y=0)
|
||||
// 1 bit - nonnull
|
||||
// 4 bits type record
|
||||
// 8 bits size (5)
|
||||
// 1 bit uncompressed
|
||||
// 40 bits "Point"
|
||||
// 54 total:
|
||||
assertEquals( 54, Lynon.encode("Point").size )
|
||||
assertEquals( 7, Lynon.encode("Point").toBuffer().size )
|
||||
|
||||
// 1 bit - nonnull
|
||||
// 4 bits type record
|
||||
assertEquals( 5, Lynon.encode(0).size )
|
||||
|
||||
class Empty()
|
||||
// 1 bit non-null
|
||||
// 4 bits type record
|
||||
// 54 bits "Empty"
|
||||
// 4 bits list size
|
||||
// dont know where 1 bit for not cached
|
||||
assertEquals( 64, Lynon.encode(Empty()).size )
|
||||
assertEquals( Empty(), Lynon.decode(Lynon.encode(Empty())) )
|
||||
|
||||
// Here the situation is dofferent: we have 2 in zeroes plus int size, but cache shrinks it
|
||||
assertEquals( 70, Lynon.encode(Point()).size )
|
||||
// two 1's added 16 bit (each short int is 8 bits)
|
||||
assertEquals( 86, Lynon.encode(Point(1,1)).size )
|
||||
assertEquals( 86, Lynon.encode(Point(1,2)).size )
|
||||
|
||||
// Now let's make it more complex: we add 1 var to save:
|
||||
class Poin2(x=0,y=0) {
|
||||
val z = x + y
|
||||
}
|
||||
// val must not be serialized so no change here:
|
||||
assertEquals( 86, Lynon.encode(Poin2(1,2)).size )
|
||||
|
||||
// lets check size of homogenous list of one small int
|
||||
// 8 bits 3
|
||||
// 4 bits type
|
||||
// 8 bits list size
|
||||
// 2 bits not cached and not null
|
||||
// 4 bits element type
|
||||
assertEquals( 27, Lynon.encode([3]).size)
|
||||
|
||||
class Poin3(x=0,y=0) {
|
||||
var z = x + y
|
||||
}
|
||||
// var must be serialized, but caching could reduce size:
|
||||
assert( Lynon.encode(Poin3(1,2)).size <= 110)
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user