Support .decodeSequentially call on JVM and Native and remove READ_ALL handling from all platforms
Fix codegen test Ignore JVM IR codegen test for a while since it requires updated kotlinx-serialization-runtime in classpath
This commit is contained in:
+54
-44
@@ -17,9 +17,11 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
|
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||||
|
import org.jetbrains.kotlin.ir.util.withScope
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||||
@@ -331,8 +333,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
|||||||
val flagVar = irTemporaryVar(irBoolean(true), "flag")
|
val flagVar = irTemporaryVar(irBoolean(true), "flag")
|
||||||
|
|
||||||
val indexVar = irTemporaryVar(irInt(0), "index")
|
val indexVar = irTemporaryVar(irInt(0), "index")
|
||||||
// val readAll = irTemporaryVar(irBoolean(false), "readAll", parent = loadFunc)
|
|
||||||
//
|
|
||||||
// calculating bit mask vars
|
// calculating bit mask vars
|
||||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||||
|
|
||||||
@@ -358,54 +359,61 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
|||||||
)
|
)
|
||||||
val localInput = irTemporary(call, "input")
|
val localInput = irTemporary(call, "input")
|
||||||
|
|
||||||
+irWhile().also { loop ->
|
// prepare all .decodeXxxElement calls
|
||||||
|
val decoderCalls: List<Pair<Int, IrExpression>> =
|
||||||
|
serializableProperties.mapIndexed { index, property ->
|
||||||
|
val body = irBlock {
|
||||||
|
val sti = getSerialTypeInfo(property)
|
||||||
|
val innerSerial = serializerInstance(
|
||||||
|
this@SerializerIrGenerator,
|
||||||
|
loadFunc.dispatchReceiverParameter!!,
|
||||||
|
sti.serializer,
|
||||||
|
property.module,
|
||||||
|
property.type,
|
||||||
|
genericIndex = property.genericIndex
|
||||||
|
)
|
||||||
|
// todo: update
|
||||||
|
val decodeFuncToCall =
|
||||||
|
(if (innerSerial != null) "${CallingConventions.decode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}"
|
||||||
|
else "${CallingConventions.decode}${sti.elementMethodPrefix}${CallingConventions.elementPostfix}")
|
||||||
|
.let {
|
||||||
|
inputClass.referenceMethod(it)
|
||||||
|
}
|
||||||
|
val typeArgs =
|
||||||
|
if (decodeFuncToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type.toIrType()) else listOf()
|
||||||
|
val args = mutableListOf<IrExpression>(localSerialDesc.get(), irInt(index))
|
||||||
|
if (innerSerial != null)
|
||||||
|
args.add(innerSerial)
|
||||||
|
// local$i = localInput.decode...(...)
|
||||||
|
+irSetVar(
|
||||||
|
localProps[index].symbol,
|
||||||
|
irInvoke(localInput.get(), decodeFuncToCall, typeArgs, args, returnTypeHint = property.type.toIrType())
|
||||||
|
)
|
||||||
|
// bitMask[i] |= 1 << x
|
||||||
|
val bitPos = 1 shl (index % 32)
|
||||||
|
val or = irBinOp(OperatorNameConventions.OR, bitMasks[index / 32].get(), irInt(bitPos))
|
||||||
|
+irSetVar(bitMasks[index / 32].symbol, or)
|
||||||
|
}
|
||||||
|
index to body
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (decoder.decodeSequentially())
|
||||||
|
val decodeSequentiallyCall = irInvoke(localInput.get(), inputClass.referenceMethod(CallingConventions.decodeSequentially))
|
||||||
|
|
||||||
|
val sequentialPart = irBlock {
|
||||||
|
decoderCalls.forEach { (_, expr) -> +expr.deepCopyWithVariables() }
|
||||||
|
}
|
||||||
|
|
||||||
|
val byIndexPart: IrExpression = irWhile().also { loop ->
|
||||||
loop.condition = flagVar.get()
|
loop.condition = flagVar.get()
|
||||||
loop.body = irBlock {
|
loop.body = irBlock {
|
||||||
val readElementF = inputClass.referenceMethod(CallingConventions.decodeElementIndex)
|
val readElementF = inputClass.referenceMethod(CallingConventions.decodeElementIndex)
|
||||||
+irSetVar(indexVar.symbol, irInvoke(localInput.get(), readElementF, localSerialDesc.get()))
|
+irSetVar(indexVar.symbol, irInvoke(localInput.get(), readElementF, localSerialDesc.get()))
|
||||||
+irWhen {
|
+irWhen {
|
||||||
// if index == -2 (READ_ALL) todo...
|
|
||||||
|
|
||||||
// if index == -1 (READ_DONE) break loop
|
// if index == -1 (READ_DONE) break loop
|
||||||
+IrBranchImpl(irEquals(indexVar.get(), irInt(-1)), irSetVar(flagVar.symbol, irBoolean(false)))
|
+IrBranchImpl(irEquals(indexVar.get(), irInt(-1)), irSetVar(flagVar.symbol, irBoolean(false)))
|
||||||
|
|
||||||
val branchBodies: List<Pair<Int, IrExpression>> =
|
decoderCalls.forEach { (i, e) -> +IrBranchImpl(irEquals(indexVar.get(), irInt(i)), e) }
|
||||||
serializableProperties.mapIndexed { index, property ->
|
|
||||||
val body = irBlock {
|
|
||||||
val sti = getSerialTypeInfo(property)
|
|
||||||
val innerSerial = serializerInstance(
|
|
||||||
this@SerializerIrGenerator,
|
|
||||||
loadFunc.dispatchReceiverParameter!!,
|
|
||||||
sti.serializer,
|
|
||||||
property.module,
|
|
||||||
property.type,
|
|
||||||
genericIndex = property.genericIndex
|
|
||||||
)
|
|
||||||
// todo: update
|
|
||||||
val decodeFuncToCall =
|
|
||||||
(if (innerSerial != null) "${CallingConventions.decode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}"
|
|
||||||
else "${CallingConventions.decode}${sti.elementMethodPrefix}${CallingConventions.elementPostfix}")
|
|
||||||
.let {
|
|
||||||
inputClass.referenceMethod(it)
|
|
||||||
}
|
|
||||||
val typeArgs =
|
|
||||||
if (decodeFuncToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type.toIrType()) else listOf()
|
|
||||||
val args = mutableListOf<IrExpression>(localSerialDesc.get(), irInt(index))
|
|
||||||
if (innerSerial != null)
|
|
||||||
args.add(innerSerial)
|
|
||||||
// local$i = localInput.decode...(...)
|
|
||||||
+irSetVar(
|
|
||||||
localProps[index].symbol,
|
|
||||||
irInvoke(localInput.get(), decodeFuncToCall, typeArgs, args, returnTypeHint = property.type.toIrType())
|
|
||||||
)
|
|
||||||
// bitMask[i] |= 1 << x
|
|
||||||
val bitPos = 1 shl (index % 32)
|
|
||||||
val or = irBinOp(OperatorNameConventions.OR, bitMasks[index / 32].get(), irInt(bitPos))
|
|
||||||
+irSetVar(bitMasks[index / 32].symbol, or)
|
|
||||||
}
|
|
||||||
index to body
|
|
||||||
}
|
|
||||||
branchBodies.forEach { (i, e) -> +IrBranchImpl(irEquals(indexVar.get(), irInt(i)), e) }
|
|
||||||
|
|
||||||
// throw exception on unknown field
|
// throw exception on unknown field
|
||||||
val exceptionCtor =
|
val exceptionCtor =
|
||||||
@@ -425,6 +433,8 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+irIfThenElse(compilerContext.irBuiltIns.unitType, decodeSequentiallyCall, sequentialPart, byIndexPart)
|
||||||
|
|
||||||
//input.endStructure(...)
|
//input.endStructure(...)
|
||||||
val endFunc = inputClass.referenceMethod(CallingConventions.end)
|
val endFunc = inputClass.referenceMethod(CallingConventions.end)
|
||||||
+irInvoke(
|
+irInvoke(
|
||||||
|
|||||||
+3
-12
@@ -244,8 +244,7 @@ open class SerializerJsTranslator(
|
|||||||
|
|
||||||
// var index = -1, readAll = false
|
// var index = -1, readAll = false
|
||||||
val indexVar = JsNameRef(jsFun.scope.declareFreshName("index"))
|
val indexVar = JsNameRef(jsFun.scope.declareFreshName("index"))
|
||||||
val readAllVar = JsNameRef(jsFun.scope.declareFreshName("readAll"))
|
+JsVars(JsVars.JsVar(indexVar.name))
|
||||||
+JsVars(JsVars.JsVar(indexVar.name), JsVars.JsVar(readAllVar.name, JsBooleanLiteral(false)))
|
|
||||||
|
|
||||||
// calculating bit mask vars
|
// calculating bit mask vars
|
||||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||||
@@ -283,14 +282,7 @@ open class SerializerJsTranslator(
|
|||||||
).makeStmt()
|
).makeStmt()
|
||||||
// switch(index)
|
// switch(index)
|
||||||
jsSwitch(indexVar) {
|
jsSwitch(indexVar) {
|
||||||
// -2: readAll = true
|
// all properties
|
||||||
case(JsIntLiteral(-2)) {
|
|
||||||
+JsAstUtils.assignment(
|
|
||||||
readAllVar,
|
|
||||||
JsBooleanLiteral(true)
|
|
||||||
).makeStmt()
|
|
||||||
}
|
|
||||||
// all properties
|
|
||||||
for ((i, property) in serializableProperties.withIndex()) {
|
for ((i, property) in serializableProperties.withIndex()) {
|
||||||
case(JsIntLiteral(i)) {
|
case(JsIntLiteral(i)) {
|
||||||
// input.readXxxElementValue
|
// input.readXxxElementValue
|
||||||
@@ -366,8 +358,7 @@ open class SerializerJsTranslator(
|
|||||||
bitMasks[bitMaskOff(i)],
|
bitMasks[bitMaskOff(i)],
|
||||||
JsIntLiteral(bitPos)
|
JsIntLiteral(bitPos)
|
||||||
).makeStmt()
|
).makeStmt()
|
||||||
// if (!readAll) break
|
+JsBreak()
|
||||||
+JsIf(JsAstUtils.not(readAllVar), JsBreak())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// case -1: break loop
|
// case -1: break loop
|
||||||
|
|||||||
+2
-3
@@ -76,9 +76,8 @@ val OPT_MASK_TYPE: Type = Type.INT_TYPE
|
|||||||
val OPT_MASK_BITS = 32
|
val OPT_MASK_BITS = 32
|
||||||
|
|
||||||
// compare with zero. if result == 0, property was not seen.
|
// compare with zero. if result == 0, property was not seen.
|
||||||
internal fun InstructionAdapter.genValidateProperty(index: Int, bitMaskPos: (Int) -> Int) {
|
internal fun InstructionAdapter.genValidateProperty(index: Int, bitMaskAddress: Int) {
|
||||||
val addr = bitMaskPos(index)
|
load(bitMaskAddress, OPT_MASK_TYPE)
|
||||||
load(addr, OPT_MASK_TYPE)
|
|
||||||
iconst(1 shl (index % OPT_MASK_BITS))
|
iconst(1 shl (index % OPT_MASK_BITS))
|
||||||
and(OPT_MASK_TYPE)
|
and(OPT_MASK_TYPE)
|
||||||
iconst(0)
|
iconst(0)
|
||||||
|
|||||||
+2
-2
@@ -188,7 +188,7 @@ class SerializableCodegenImpl(
|
|||||||
val propType = prop.asmType
|
val propType = prop.asmType
|
||||||
if (!prop.optional) {
|
if (!prop.optional) {
|
||||||
// primary were validated before constructor call
|
// primary were validated before constructor call
|
||||||
genValidateProperty(i, bitMaskOff)
|
genValidateProperty(i, bitMaskOff(i))
|
||||||
val nonThrowLabel = Label()
|
val nonThrowLabel = Label()
|
||||||
ificmpne(nonThrowLabel)
|
ificmpne(nonThrowLabel)
|
||||||
genExceptionThrow(serializationExceptionMissingFieldName, prop.name)
|
genExceptionThrow(serializationExceptionMissingFieldName, prop.name)
|
||||||
@@ -198,7 +198,7 @@ class SerializableCodegenImpl(
|
|||||||
load(propOffset, propType)
|
load(propOffset, propType)
|
||||||
putfield(thisAsmType.internalName, prop.descriptor.name.asString(), propType.descriptor)
|
putfield(thisAsmType.internalName, prop.descriptor.name.asString(), propType.descriptor)
|
||||||
} else {
|
} else {
|
||||||
genValidateProperty(i, bitMaskOff)
|
genValidateProperty(i, bitMaskOff(i))
|
||||||
val setLbl = Label()
|
val setLbl = Label()
|
||||||
val nextLabel = Label()
|
val nextLabel = Label()
|
||||||
ificmpeq(setLbl)
|
ificmpeq(setLbl)
|
||||||
|
|||||||
+95
-73
@@ -299,15 +299,11 @@ open class SerializerCodegenImpl(
|
|||||||
val inputVar = 1
|
val inputVar = 1
|
||||||
val descVar = 2
|
val descVar = 2
|
||||||
val indexVar = 3
|
val indexVar = 3
|
||||||
val readAllVar = 4
|
val bitMaskBase = 4
|
||||||
val bitMaskBase = 5
|
|
||||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||||
val bitMaskOff = fun(it: Int): Int { return bitMaskBase + bitMaskSlotAt(it) }
|
val bitMaskOff = fun(it: Int): Int { return bitMaskBase + bitMaskSlotAt(it) }
|
||||||
val propsStartVar = bitMaskBase + blocksCnt
|
val propsStartVar = bitMaskBase + blocksCnt
|
||||||
stackSerialClassDesc(descVar)
|
stackSerialClassDesc(descVar)
|
||||||
// boolean readAll = false
|
|
||||||
iconst(0)
|
|
||||||
store(readAllVar, Type.BOOLEAN_TYPE)
|
|
||||||
// initialize bit mask
|
// initialize bit mask
|
||||||
for (i in 0 until blocksCnt) {
|
for (i in 0 until blocksCnt) {
|
||||||
//int bitMaskN = 0
|
//int bitMaskN = 0
|
||||||
@@ -332,8 +328,31 @@ open class SerializerCodegenImpl(
|
|||||||
")" + kInputType.descriptor
|
")" + kInputType.descriptor
|
||||||
)
|
)
|
||||||
store(inputVar, kInputType)
|
store(inputVar, kInputType)
|
||||||
// readElement: int index = input.readElement(classDesc)
|
|
||||||
val readElementLabel = Label()
|
val readElementLabel = Label()
|
||||||
|
val readEndLabel = Label()
|
||||||
|
// if (decoder.decodeSequentially)
|
||||||
|
load(inputVar, kInputType)
|
||||||
|
invokeinterface(
|
||||||
|
kInputType.internalName, CallingConventions.decodeSequentially,
|
||||||
|
"()Z"
|
||||||
|
)
|
||||||
|
ifeq(readElementLabel)
|
||||||
|
// decodeSequentially = true
|
||||||
|
propVar = propsStartVar
|
||||||
|
for ((index, property) in serializableProperties.withIndex()) {
|
||||||
|
val propertyType = codegen.typeMapper.mapType(property.type)
|
||||||
|
callReadProperty(property, propertyType, index, inputVar, descVar, -1, propVar)
|
||||||
|
propVar += propertyType.size
|
||||||
|
}
|
||||||
|
// set all bit masks to true
|
||||||
|
for (maskVar in bitMaskBase until propsStartVar) {
|
||||||
|
iconst(Int.MAX_VALUE)
|
||||||
|
store(maskVar, OPT_MASK_TYPE)
|
||||||
|
}
|
||||||
|
// go to end
|
||||||
|
goTo(readEndLabel)
|
||||||
|
// branch with decodeSequentially = false
|
||||||
|
// readElement: int index = input.readElement(classDesc)
|
||||||
visitLabel(readElementLabel)
|
visitLabel(readElementLabel)
|
||||||
load(inputVar, kInputType)
|
load(inputVar, kInputType)
|
||||||
load(descVar, descType)
|
load(descVar, descType)
|
||||||
@@ -344,78 +363,24 @@ open class SerializerCodegenImpl(
|
|||||||
store(indexVar, Type.INT_TYPE)
|
store(indexVar, Type.INT_TYPE)
|
||||||
// switch(index)
|
// switch(index)
|
||||||
val labeledProperties = serializableProperties.filter { !it.transient }
|
val labeledProperties = serializableProperties.filter { !it.transient }
|
||||||
val readAllLabel = Label()
|
|
||||||
val readEndLabel = Label()
|
|
||||||
val incorrectIndLabel = Label()
|
val incorrectIndLabel = Label()
|
||||||
val labels = arrayOfNulls<Label>(labeledProperties.size + 2)
|
val labels = arrayOfNulls<Label>(labeledProperties.size + 1)
|
||||||
labels[0] = readAllLabel // READ_ALL
|
labels[0] = readEndLabel // READ_DONE
|
||||||
labels[1] = readEndLabel // READ_DONE
|
|
||||||
for (i in labeledProperties.indices) {
|
for (i in labeledProperties.indices) {
|
||||||
labels[i + 2] = Label()
|
labels[i + 1] = Label()
|
||||||
}
|
}
|
||||||
load(indexVar, Type.INT_TYPE)
|
load(indexVar, Type.INT_TYPE)
|
||||||
tableswitch(-2, labeledProperties.size - 1, incorrectIndLabel, *labels)
|
tableswitch(-1, labeledProperties.size - 1, incorrectIndLabel, *labels)
|
||||||
// readAll: readAll := true
|
|
||||||
visitLabel(readAllLabel)
|
|
||||||
iconst(1)
|
|
||||||
store(readAllVar, Type.BOOLEAN_TYPE)
|
|
||||||
// loop for all properties
|
// loop for all properties
|
||||||
propVar = propsStartVar
|
propVar = propsStartVar
|
||||||
var labelNum = 0
|
var labelNum = 0
|
||||||
for ((index, property) in serializableProperties.withIndex()) {
|
for ((index, property) in serializableProperties.withIndex()) {
|
||||||
val propertyType = codegen.typeMapper.mapType(property.type)
|
val propertyType = codegen.typeMapper.mapType(property.type)
|
||||||
if (!property.transient) {
|
if (!property.transient) {
|
||||||
|
val propertyAddressInBitMask = bitMaskOff(index)
|
||||||
// labelI:
|
// labelI:
|
||||||
visitLabel(labels[labelNum + 2])
|
visitLabel(labels[labelNum + 1])
|
||||||
// propX := input.readXxxValue(value)
|
callReadProperty(property, propertyType, index, inputVar, descVar, propertyAddressInBitMask, propVar)
|
||||||
load(inputVar, kInputType)
|
|
||||||
load(descVar, descType)
|
|
||||||
iconst(labelNum)
|
|
||||||
|
|
||||||
val sti = getSerialTypeInfo(property, propertyType)
|
|
||||||
val useSerializer = stackValueSerializerInstanceFromSerializer(codegen, sti, this@SerializerCodegenImpl)
|
|
||||||
val unknownSer = (!useSerializer && sti.elementMethodPrefix.isEmpty())
|
|
||||||
if (unknownSer) {
|
|
||||||
aconst(codegen.typeMapper.mapType(property.type))
|
|
||||||
AsmUtil.wrapJavaClassIntoKClass(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun produceCall(update: Boolean) {
|
|
||||||
invokeinterface(
|
|
||||||
kInputType.internalName,
|
|
||||||
(if (update) CallingConventions.update else CallingConventions.decode) + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + CallingConventions.elementPostfix,
|
|
||||||
"(" + descType.descriptor + "I" +
|
|
||||||
(if (useSerializer) kSerialLoaderType.descriptor else "")
|
|
||||||
+ (if (unknownSer) AsmTypes.K_CLASS_TYPE.descriptor else "")
|
|
||||||
+ (if (update) sti.type.descriptor else "")
|
|
||||||
+ ")" + (if (sti.unit) "V" else sti.type.descriptor)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useSerializer) {
|
|
||||||
// we can choose either it is read or update
|
|
||||||
val readLabel = Label()
|
|
||||||
val endL = Label()
|
|
||||||
genValidateProperty(index, bitMaskOff)
|
|
||||||
ificmpeq(readLabel)
|
|
||||||
load(propVar, propertyType)
|
|
||||||
StackValue.coerce(propertyType, sti.type, this)
|
|
||||||
produceCall(true)
|
|
||||||
goTo(endL)
|
|
||||||
visitLabel(readLabel)
|
|
||||||
produceCall(false)
|
|
||||||
visitLabel(endL)
|
|
||||||
} else {
|
|
||||||
// update not supported for primitive types
|
|
||||||
produceCall(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sti.unit) {
|
|
||||||
StackValue.putUnitInstance(this)
|
|
||||||
} else {
|
|
||||||
StackValue.coerce(sti.type, propertyType, this)
|
|
||||||
}
|
|
||||||
store(propVar, propertyType)
|
|
||||||
|
|
||||||
// mark read bit in mask
|
// mark read bit in mask
|
||||||
// bitMask = bitMask | 1 << index
|
// bitMask = bitMask | 1 << index
|
||||||
@@ -424,10 +389,7 @@ open class SerializerCodegenImpl(
|
|||||||
iconst(1 shl (index % OPT_MASK_BITS))
|
iconst(1 shl (index % OPT_MASK_BITS))
|
||||||
or(OPT_MASK_TYPE)
|
or(OPT_MASK_TYPE)
|
||||||
store(addr, OPT_MASK_TYPE)
|
store(addr, OPT_MASK_TYPE)
|
||||||
// if (readAll == false) goto readElement
|
goTo(readElementLabel)
|
||||||
load(readAllVar, Type.BOOLEAN_TYPE)
|
|
||||||
iconst(0)
|
|
||||||
ificmpeq(readElementLabel)
|
|
||||||
labelNum++
|
labelNum++
|
||||||
}
|
}
|
||||||
// next
|
// next
|
||||||
@@ -456,7 +418,7 @@ open class SerializerCodegenImpl(
|
|||||||
null
|
null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
genValidateProperty(i, bitMaskOff)
|
genValidateProperty(i, bitMaskOff(i))
|
||||||
// todo: print name of each variable?
|
// todo: print name of each variable?
|
||||||
ificmpeq(throwLabel)
|
ificmpeq(throwLabel)
|
||||||
}
|
}
|
||||||
@@ -499,6 +461,66 @@ open class SerializerCodegenImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun InstructionAdapter.callReadProperty(
|
||||||
|
property: SerializableProperty,
|
||||||
|
propertyType: Type,
|
||||||
|
index: Int,
|
||||||
|
inputVar: Int,
|
||||||
|
descriptorVar: Int,
|
||||||
|
propertyAddressInBitMask: Int,
|
||||||
|
propertyVar: Int
|
||||||
|
) {
|
||||||
|
// propX := input.readXxxValue(value)
|
||||||
|
load(inputVar, kInputType)
|
||||||
|
load(descriptorVar, descType)
|
||||||
|
iconst(index)
|
||||||
|
|
||||||
|
val sti = getSerialTypeInfo(property, propertyType)
|
||||||
|
val useSerializer = stackValueSerializerInstanceFromSerializer(codegen, sti, this@SerializerCodegenImpl)
|
||||||
|
val unknownSer = (!useSerializer && sti.elementMethodPrefix.isEmpty())
|
||||||
|
if (unknownSer) {
|
||||||
|
aconst(codegen.typeMapper.mapType(property.type))
|
||||||
|
AsmUtil.wrapJavaClassIntoKClass(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun produceCall(update: Boolean) {
|
||||||
|
invokeinterface(
|
||||||
|
kInputType.internalName,
|
||||||
|
(if (update) CallingConventions.update else CallingConventions.decode) + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + CallingConventions.elementPostfix,
|
||||||
|
"(" + descType.descriptor + "I" +
|
||||||
|
(if (useSerializer) kSerialLoaderType.descriptor else "")
|
||||||
|
+ (if (unknownSer) AsmTypes.K_CLASS_TYPE.descriptor else "")
|
||||||
|
+ (if (update) sti.type.descriptor else "")
|
||||||
|
+ ")" + (if (sti.unit) "V" else sti.type.descriptor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useSerializer && propertyAddressInBitMask != -1) {
|
||||||
|
// we can choose either it is read or update
|
||||||
|
val readLabel = Label()
|
||||||
|
val endL = Label()
|
||||||
|
genValidateProperty(index, propertyAddressInBitMask)
|
||||||
|
ificmpeq(readLabel)
|
||||||
|
load(propertyVar, propertyType)
|
||||||
|
StackValue.coerce(propertyType, sti.type, this)
|
||||||
|
produceCall(true)
|
||||||
|
goTo(endL)
|
||||||
|
visitLabel(readLabel)
|
||||||
|
produceCall(false)
|
||||||
|
visitLabel(endL)
|
||||||
|
} else {
|
||||||
|
// update not supported for primitive types or decodeSequentially
|
||||||
|
produceCall(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sti.unit) {
|
||||||
|
StackValue.putUnitInstance(this)
|
||||||
|
} else {
|
||||||
|
StackValue.coerce(sti.type, propertyType, this)
|
||||||
|
}
|
||||||
|
store(propertyVar, propertyType)
|
||||||
|
}
|
||||||
|
|
||||||
private fun InstructionAdapter.buildExternalConstructorDesc(propsStartVar: Int, bitMaskBase: Int): String {
|
private fun InstructionAdapter.buildExternalConstructorDesc(propsStartVar: Int, bitMaskBase: Int): String {
|
||||||
val constructorDesc = StringBuilder("(")
|
val constructorDesc = StringBuilder("(")
|
||||||
var propVar = propsStartVar
|
var propVar = propsStartVar
|
||||||
@@ -532,7 +554,7 @@ open class SerializerCodegenImpl(
|
|||||||
//check if property has been seen and should be set
|
//check if property has been seen and should be set
|
||||||
val nextLabel = Label()
|
val nextLabel = Label()
|
||||||
// seen = bitMask & 1 << pos != 0
|
// seen = bitMask & 1 << pos != 0
|
||||||
genValidateProperty(i, bitMaskPos)
|
genValidateProperty(i, bitMaskPos(i))
|
||||||
if (property.optional) {
|
if (property.optional) {
|
||||||
// if (seen)
|
// if (seen)
|
||||||
// set
|
// set
|
||||||
|
|||||||
+1
@@ -95,6 +95,7 @@ object CallingConventions {
|
|||||||
const val encodeEnum = "encodeEnum"
|
const val encodeEnum = "encodeEnum"
|
||||||
const val decodeEnum = "decodeEnum"
|
const val decodeEnum = "decodeEnum"
|
||||||
const val decodeElementIndex = "decodeElementIndex"
|
const val decodeElementIndex = "decodeElementIndex"
|
||||||
|
const val decodeSequentially = "decodeSequentially"
|
||||||
const val elementPostfix = "Element"
|
const val elementPostfix = "Element"
|
||||||
const val shouldEncodeDefault = "shouldEncodeElementDefault"
|
const val shouldEncodeDefault = "shouldEncodeElementDefault"
|
||||||
|
|
||||||
|
|||||||
+2
@@ -9,6 +9,7 @@ import com.intellij.testFramework.TestDataPath;
|
|||||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
import org.jetbrains.kotlin.test.TestMetadata;
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -19,6 +20,7 @@ import java.util.regex.Pattern;
|
|||||||
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen")
|
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
@Ignore // todo: unignore when new serialziation version will be publicly available & update it in build.gradle.kts
|
||||||
public class SerializationIrBytecodeListingTestGenerated extends AbstractSerializationIrBytecodeListingTest {
|
public class SerializationIrBytecodeListingTestGenerated extends AbstractSerializationIrBytecodeListingTest {
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
|||||||
+86
-58
@@ -62,16 +62,31 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
|||||||
ASTORE (2)
|
ASTORE (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ISTORE (4)
|
ISTORE (4)
|
||||||
ICONST_0
|
|
||||||
ISTORE (5)
|
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
ASTORE (6)
|
ASTORE (5)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ANEWARRAY
|
ANEWARRAY
|
||||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||||
ASTORE (1)
|
ASTORE (1)
|
||||||
|
ALOAD (1)
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSequentially, ()Z)
|
||||||
|
IFEQ (L1)
|
||||||
|
ALOAD (1)
|
||||||
|
ALOAD (2)
|
||||||
|
ICONST_0
|
||||||
|
NEW
|
||||||
|
DUP
|
||||||
|
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||||
|
CHECKCAST
|
||||||
|
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||||
|
CHECKCAST
|
||||||
|
ASTORE (5)
|
||||||
|
LDC (2147483647)
|
||||||
|
ISTORE (4)
|
||||||
|
GOTO (L2)
|
||||||
LABEL (L1)
|
LABEL (L1)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
@@ -79,9 +94,6 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
|||||||
ISTORE (3)
|
ISTORE (3)
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
TABLESWITCH
|
TABLESWITCH
|
||||||
LABEL (L2)
|
|
||||||
ICONST_1
|
|
||||||
ISTORE (4)
|
|
||||||
LABEL (L3)
|
LABEL (L3)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
@@ -91,43 +103,42 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
|||||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
IAND
|
IAND
|
||||||
IFEQ (L4)
|
IFEQ (L4)
|
||||||
ALOAD (6)
|
ALOAD (5)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
||||||
GOTO (L5)
|
GOTO (L5)
|
||||||
LABEL (L4)
|
LABEL (L4)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||||
LABEL (L5)
|
LABEL (L5)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ASTORE (6)
|
ASTORE (5)
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
IOR
|
IOR
|
||||||
ISTORE (5)
|
ISTORE (4)
|
||||||
ILOAD (4)
|
GOTO (L1)
|
||||||
IFEQ (L1)
|
LABEL (L2)
|
||||||
LABEL (L6)
|
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ALOAD (6)
|
ALOAD (5)
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
INVOKESPECIAL (ListOfUsers, <init>, (ILjava/util/List;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
INVOKESPECIAL (ListOfUsers, <init>, (ILjava/util/List;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||||
ARETURN
|
ARETURN
|
||||||
LABEL (L7)
|
LABEL (L6)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ATHROW
|
ATHROW
|
||||||
LABEL (L8)
|
LABEL (L7)
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
||||||
@@ -348,16 +359,28 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
|||||||
ASTORE (2)
|
ASTORE (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ISTORE (4)
|
ISTORE (4)
|
||||||
ICONST_0
|
|
||||||
ISTORE (5)
|
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
ASTORE (6)
|
ASTORE (5)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ANEWARRAY
|
ANEWARRAY
|
||||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||||
ASTORE (1)
|
ASTORE (1)
|
||||||
|
ALOAD (1)
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSequentially, ()Z)
|
||||||
|
IFEQ (L1)
|
||||||
|
ALOAD (1)
|
||||||
|
ALOAD (2)
|
||||||
|
ICONST_0
|
||||||
|
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||||
|
CHECKCAST
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||||
|
CHECKCAST
|
||||||
|
ASTORE (5)
|
||||||
|
LDC (2147483647)
|
||||||
|
ISTORE (4)
|
||||||
|
GOTO (L2)
|
||||||
LABEL (L1)
|
LABEL (L1)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
@@ -365,52 +388,48 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
|||||||
ISTORE (3)
|
ISTORE (3)
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
TABLESWITCH
|
TABLESWITCH
|
||||||
LABEL (L2)
|
|
||||||
ICONST_1
|
|
||||||
ISTORE (4)
|
|
||||||
LABEL (L3)
|
LABEL (L3)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
IAND
|
IAND
|
||||||
IFEQ (L4)
|
IFEQ (L4)
|
||||||
ALOAD (6)
|
ALOAD (5)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
||||||
GOTO (L5)
|
GOTO (L5)
|
||||||
LABEL (L4)
|
LABEL (L4)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||||
LABEL (L5)
|
LABEL (L5)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ASTORE (6)
|
ASTORE (5)
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
IOR
|
IOR
|
||||||
ISTORE (5)
|
ISTORE (4)
|
||||||
ILOAD (4)
|
GOTO (L1)
|
||||||
IFEQ (L1)
|
LABEL (L2)
|
||||||
LABEL (L6)
|
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ALOAD (6)
|
ALOAD (5)
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
INVOKESPECIAL (OptionalUser, <init>, (ILUser;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
INVOKESPECIAL (OptionalUser, <init>, (ILUser;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||||
ARETURN
|
ARETURN
|
||||||
LABEL (L7)
|
LABEL (L6)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ATHROW
|
ATHROW
|
||||||
LABEL (L8)
|
LABEL (L7)
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
||||||
@@ -691,18 +710,32 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
|||||||
ASTORE (2)
|
ASTORE (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ISTORE (4)
|
ISTORE (4)
|
||||||
ICONST_0
|
ACONST_NULL
|
||||||
ISTORE (5)
|
ASTORE (5)
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
ASTORE (6)
|
ASTORE (6)
|
||||||
ACONST_NULL
|
|
||||||
ASTORE (7)
|
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
ANEWARRAY
|
ANEWARRAY
|
||||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||||
ASTORE (1)
|
ASTORE (1)
|
||||||
|
ALOAD (1)
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSequentially, ()Z)
|
||||||
|
IFEQ (L1)
|
||||||
|
ALOAD (1)
|
||||||
|
ALOAD (2)
|
||||||
|
ICONST_0
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||||
|
ASTORE (5)
|
||||||
|
ALOAD (1)
|
||||||
|
ALOAD (2)
|
||||||
|
ICONST_1
|
||||||
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||||
|
ASTORE (6)
|
||||||
|
LDC (2147483647)
|
||||||
|
ISTORE (4)
|
||||||
|
GOTO (L2)
|
||||||
LABEL (L1)
|
LABEL (L1)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
@@ -710,53 +743,48 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
|||||||
ISTORE (3)
|
ISTORE (3)
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
TABLESWITCH
|
TABLESWITCH
|
||||||
LABEL (L2)
|
|
||||||
ICONST_1
|
|
||||||
ISTORE (4)
|
|
||||||
LABEL (L3)
|
LABEL (L3)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_0
|
ICONST_0
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||||
ASTORE (6)
|
ASTORE (5)
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
IOR
|
IOR
|
||||||
ISTORE (5)
|
ISTORE (4)
|
||||||
ILOAD (4)
|
GOTO (L1)
|
||||||
IFEQ (L1)
|
|
||||||
LABEL (L4)
|
LABEL (L4)
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
ICONST_1
|
ICONST_1
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||||
ASTORE (7)
|
ASTORE (6)
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
ICONST_2
|
ICONST_2
|
||||||
IOR
|
IOR
|
||||||
ISTORE (5)
|
ISTORE (4)
|
||||||
ILOAD (4)
|
GOTO (L1)
|
||||||
IFEQ (L1)
|
LABEL (L2)
|
||||||
LABEL (L5)
|
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
ALOAD (2)
|
ALOAD (2)
|
||||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (5)
|
ILOAD (4)
|
||||||
|
ALOAD (5)
|
||||||
ALOAD (6)
|
ALOAD (6)
|
||||||
ALOAD (7)
|
|
||||||
ACONST_NULL
|
ACONST_NULL
|
||||||
INVOKESPECIAL (User, <init>, (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
INVOKESPECIAL (User, <init>, (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||||
ARETURN
|
ARETURN
|
||||||
LABEL (L6)
|
LABEL (L5)
|
||||||
NEW
|
NEW
|
||||||
DUP
|
DUP
|
||||||
ILOAD (3)
|
ILOAD (3)
|
||||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||||
CHECKCAST
|
CHECKCAST
|
||||||
ATHROW
|
ATHROW
|
||||||
LABEL (L7)
|
LABEL (L6)
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user