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.IrFunctionSymbol
|
||||
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.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
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 indexVar = irTemporaryVar(irInt(0), "index")
|
||||
// val readAll = irTemporaryVar(irBoolean(false), "readAll", parent = loadFunc)
|
||||
//
|
||||
|
||||
// calculating bit mask vars
|
||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||
|
||||
@@ -358,54 +359,61 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
||||
)
|
||||
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.body = irBlock {
|
||||
val readElementF = inputClass.referenceMethod(CallingConventions.decodeElementIndex)
|
||||
+irSetVar(indexVar.symbol, irInvoke(localInput.get(), readElementF, localSerialDesc.get()))
|
||||
+irWhen {
|
||||
// if index == -2 (READ_ALL) todo...
|
||||
|
||||
// if index == -1 (READ_DONE) break loop
|
||||
+IrBranchImpl(irEquals(indexVar.get(), irInt(-1)), irSetVar(flagVar.symbol, irBoolean(false)))
|
||||
|
||||
val branchBodies: 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
|
||||
}
|
||||
branchBodies.forEach { (i, e) -> +IrBranchImpl(irEquals(indexVar.get(), irInt(i)), e) }
|
||||
decoderCalls.forEach { (i, e) -> +IrBranchImpl(irEquals(indexVar.get(), irInt(i)), e) }
|
||||
|
||||
// throw exception on unknown field
|
||||
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(...)
|
||||
val endFunc = inputClass.referenceMethod(CallingConventions.end)
|
||||
+irInvoke(
|
||||
|
||||
+3
-12
@@ -244,8 +244,7 @@ open class SerializerJsTranslator(
|
||||
|
||||
// var index = -1, readAll = false
|
||||
val indexVar = JsNameRef(jsFun.scope.declareFreshName("index"))
|
||||
val readAllVar = JsNameRef(jsFun.scope.declareFreshName("readAll"))
|
||||
+JsVars(JsVars.JsVar(indexVar.name), JsVars.JsVar(readAllVar.name, JsBooleanLiteral(false)))
|
||||
+JsVars(JsVars.JsVar(indexVar.name))
|
||||
|
||||
// calculating bit mask vars
|
||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||
@@ -283,14 +282,7 @@ open class SerializerJsTranslator(
|
||||
).makeStmt()
|
||||
// switch(index)
|
||||
jsSwitch(indexVar) {
|
||||
// -2: readAll = true
|
||||
case(JsIntLiteral(-2)) {
|
||||
+JsAstUtils.assignment(
|
||||
readAllVar,
|
||||
JsBooleanLiteral(true)
|
||||
).makeStmt()
|
||||
}
|
||||
// all properties
|
||||
// all properties
|
||||
for ((i, property) in serializableProperties.withIndex()) {
|
||||
case(JsIntLiteral(i)) {
|
||||
// input.readXxxElementValue
|
||||
@@ -366,8 +358,7 @@ open class SerializerJsTranslator(
|
||||
bitMasks[bitMaskOff(i)],
|
||||
JsIntLiteral(bitPos)
|
||||
).makeStmt()
|
||||
// if (!readAll) break
|
||||
+JsIf(JsAstUtils.not(readAllVar), JsBreak())
|
||||
+JsBreak()
|
||||
}
|
||||
}
|
||||
// case -1: break loop
|
||||
|
||||
+2
-3
@@ -76,9 +76,8 @@ val OPT_MASK_TYPE: Type = Type.INT_TYPE
|
||||
val OPT_MASK_BITS = 32
|
||||
|
||||
// compare with zero. if result == 0, property was not seen.
|
||||
internal fun InstructionAdapter.genValidateProperty(index: Int, bitMaskPos: (Int) -> Int) {
|
||||
val addr = bitMaskPos(index)
|
||||
load(addr, OPT_MASK_TYPE)
|
||||
internal fun InstructionAdapter.genValidateProperty(index: Int, bitMaskAddress: Int) {
|
||||
load(bitMaskAddress, OPT_MASK_TYPE)
|
||||
iconst(1 shl (index % OPT_MASK_BITS))
|
||||
and(OPT_MASK_TYPE)
|
||||
iconst(0)
|
||||
|
||||
+2
-2
@@ -188,7 +188,7 @@ class SerializableCodegenImpl(
|
||||
val propType = prop.asmType
|
||||
if (!prop.optional) {
|
||||
// primary were validated before constructor call
|
||||
genValidateProperty(i, bitMaskOff)
|
||||
genValidateProperty(i, bitMaskOff(i))
|
||||
val nonThrowLabel = Label()
|
||||
ificmpne(nonThrowLabel)
|
||||
genExceptionThrow(serializationExceptionMissingFieldName, prop.name)
|
||||
@@ -198,7 +198,7 @@ class SerializableCodegenImpl(
|
||||
load(propOffset, propType)
|
||||
putfield(thisAsmType.internalName, prop.descriptor.name.asString(), propType.descriptor)
|
||||
} else {
|
||||
genValidateProperty(i, bitMaskOff)
|
||||
genValidateProperty(i, bitMaskOff(i))
|
||||
val setLbl = Label()
|
||||
val nextLabel = Label()
|
||||
ificmpeq(setLbl)
|
||||
|
||||
+95
-73
@@ -299,15 +299,11 @@ open class SerializerCodegenImpl(
|
||||
val inputVar = 1
|
||||
val descVar = 2
|
||||
val indexVar = 3
|
||||
val readAllVar = 4
|
||||
val bitMaskBase = 5
|
||||
val bitMaskBase = 4
|
||||
val blocksCnt = serializableProperties.bitMaskSlotCount()
|
||||
val bitMaskOff = fun(it: Int): Int { return bitMaskBase + bitMaskSlotAt(it) }
|
||||
val propsStartVar = bitMaskBase + blocksCnt
|
||||
stackSerialClassDesc(descVar)
|
||||
// boolean readAll = false
|
||||
iconst(0)
|
||||
store(readAllVar, Type.BOOLEAN_TYPE)
|
||||
// initialize bit mask
|
||||
for (i in 0 until blocksCnt) {
|
||||
//int bitMaskN = 0
|
||||
@@ -332,8 +328,31 @@ open class SerializerCodegenImpl(
|
||||
")" + kInputType.descriptor
|
||||
)
|
||||
store(inputVar, kInputType)
|
||||
// readElement: int index = input.readElement(classDesc)
|
||||
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)
|
||||
load(inputVar, kInputType)
|
||||
load(descVar, descType)
|
||||
@@ -344,78 +363,24 @@ open class SerializerCodegenImpl(
|
||||
store(indexVar, Type.INT_TYPE)
|
||||
// switch(index)
|
||||
val labeledProperties = serializableProperties.filter { !it.transient }
|
||||
val readAllLabel = Label()
|
||||
val readEndLabel = Label()
|
||||
val incorrectIndLabel = Label()
|
||||
val labels = arrayOfNulls<Label>(labeledProperties.size + 2)
|
||||
labels[0] = readAllLabel // READ_ALL
|
||||
labels[1] = readEndLabel // READ_DONE
|
||||
val labels = arrayOfNulls<Label>(labeledProperties.size + 1)
|
||||
labels[0] = readEndLabel // READ_DONE
|
||||
for (i in labeledProperties.indices) {
|
||||
labels[i + 2] = Label()
|
||||
labels[i + 1] = Label()
|
||||
}
|
||||
load(indexVar, Type.INT_TYPE)
|
||||
tableswitch(-2, labeledProperties.size - 1, incorrectIndLabel, *labels)
|
||||
// readAll: readAll := true
|
||||
visitLabel(readAllLabel)
|
||||
iconst(1)
|
||||
store(readAllVar, Type.BOOLEAN_TYPE)
|
||||
tableswitch(-1, labeledProperties.size - 1, incorrectIndLabel, *labels)
|
||||
// loop for all properties
|
||||
propVar = propsStartVar
|
||||
var labelNum = 0
|
||||
for ((index, property) in serializableProperties.withIndex()) {
|
||||
val propertyType = codegen.typeMapper.mapType(property.type)
|
||||
if (!property.transient) {
|
||||
val propertyAddressInBitMask = bitMaskOff(index)
|
||||
// labelI:
|
||||
visitLabel(labels[labelNum + 2])
|
||||
// propX := input.readXxxValue(value)
|
||||
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)
|
||||
visitLabel(labels[labelNum + 1])
|
||||
callReadProperty(property, propertyType, index, inputVar, descVar, propertyAddressInBitMask, propVar)
|
||||
|
||||
// mark read bit in mask
|
||||
// bitMask = bitMask | 1 << index
|
||||
@@ -424,10 +389,7 @@ open class SerializerCodegenImpl(
|
||||
iconst(1 shl (index % OPT_MASK_BITS))
|
||||
or(OPT_MASK_TYPE)
|
||||
store(addr, OPT_MASK_TYPE)
|
||||
// if (readAll == false) goto readElement
|
||||
load(readAllVar, Type.BOOLEAN_TYPE)
|
||||
iconst(0)
|
||||
ificmpeq(readElementLabel)
|
||||
goTo(readElementLabel)
|
||||
labelNum++
|
||||
}
|
||||
// next
|
||||
@@ -456,7 +418,7 @@ open class SerializerCodegenImpl(
|
||||
null
|
||||
)
|
||||
} else {
|
||||
genValidateProperty(i, bitMaskOff)
|
||||
genValidateProperty(i, bitMaskOff(i))
|
||||
// todo: print name of each variable?
|
||||
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 {
|
||||
val constructorDesc = StringBuilder("(")
|
||||
var propVar = propsStartVar
|
||||
@@ -532,7 +554,7 @@ open class SerializerCodegenImpl(
|
||||
//check if property has been seen and should be set
|
||||
val nextLabel = Label()
|
||||
// seen = bitMask & 1 << pos != 0
|
||||
genValidateProperty(i, bitMaskPos)
|
||||
genValidateProperty(i, bitMaskPos(i))
|
||||
if (property.optional) {
|
||||
// if (seen)
|
||||
// set
|
||||
|
||||
+1
@@ -95,6 +95,7 @@ object CallingConventions {
|
||||
const val encodeEnum = "encodeEnum"
|
||||
const val decodeEnum = "decodeEnum"
|
||||
const val decodeElementIndex = "decodeElementIndex"
|
||||
const val decodeSequentially = "decodeSequentially"
|
||||
const val elementPostfix = "Element"
|
||||
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.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
@@ -19,6 +20,7 @@ import java.util.regex.Pattern;
|
||||
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@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 {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
|
||||
+86
-58
@@ -62,16 +62,31 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
ASTORE (2)
|
||||
ICONST_0
|
||||
ISTORE (4)
|
||||
ICONST_0
|
||||
ISTORE (5)
|
||||
ACONST_NULL
|
||||
ASTORE (6)
|
||||
ASTORE (5)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
ANEWARRAY
|
||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||
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)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
@@ -79,9 +94,6 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
ISTORE (3)
|
||||
ILOAD (3)
|
||||
TABLESWITCH
|
||||
LABEL (L2)
|
||||
ICONST_1
|
||||
ISTORE (4)
|
||||
LABEL (L3)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
@@ -91,43 +103,42 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
||||
ILOAD (5)
|
||||
ILOAD (4)
|
||||
ICONST_1
|
||||
IAND
|
||||
IFEQ (L4)
|
||||
ALOAD (6)
|
||||
ALOAD (5)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
||||
GOTO (L5)
|
||||
LABEL (L4)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||
LABEL (L5)
|
||||
CHECKCAST
|
||||
ASTORE (6)
|
||||
ILOAD (5)
|
||||
ASTORE (5)
|
||||
ILOAD (4)
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
ILOAD (4)
|
||||
IFEQ (L1)
|
||||
LABEL (L6)
|
||||
ISTORE (4)
|
||||
GOTO (L1)
|
||||
LABEL (L2)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (5)
|
||||
ALOAD (6)
|
||||
ILOAD (4)
|
||||
ALOAD (5)
|
||||
ACONST_NULL
|
||||
INVOKESPECIAL (ListOfUsers, <init>, (ILjava/util/List;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L7)
|
||||
LABEL (L6)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (3)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
CHECKCAST
|
||||
ATHROW
|
||||
LABEL (L8)
|
||||
LABEL (L7)
|
||||
}
|
||||
|
||||
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)
|
||||
ICONST_0
|
||||
ISTORE (4)
|
||||
ICONST_0
|
||||
ISTORE (5)
|
||||
ACONST_NULL
|
||||
ASTORE (6)
|
||||
ASTORE (5)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
ANEWARRAY
|
||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||
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)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
@@ -365,52 +388,48 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
||||
ISTORE (3)
|
||||
ILOAD (3)
|
||||
TABLESWITCH
|
||||
LABEL (L2)
|
||||
ICONST_1
|
||||
ISTORE (4)
|
||||
LABEL (L3)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
ILOAD (5)
|
||||
ILOAD (4)
|
||||
ICONST_1
|
||||
IAND
|
||||
IFEQ (L4)
|
||||
ALOAD (6)
|
||||
ALOAD (5)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, updateSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;)
|
||||
GOTO (L5)
|
||||
LABEL (L4)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeSerializableElement, (Lkotlinx/serialization/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;)
|
||||
LABEL (L5)
|
||||
CHECKCAST
|
||||
ASTORE (6)
|
||||
ILOAD (5)
|
||||
ASTORE (5)
|
||||
ILOAD (4)
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
ILOAD (4)
|
||||
IFEQ (L1)
|
||||
LABEL (L6)
|
||||
ISTORE (4)
|
||||
GOTO (L1)
|
||||
LABEL (L2)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (5)
|
||||
ALOAD (6)
|
||||
ILOAD (4)
|
||||
ALOAD (5)
|
||||
ACONST_NULL
|
||||
INVOKESPECIAL (OptionalUser, <init>, (ILUser;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L7)
|
||||
LABEL (L6)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (3)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
CHECKCAST
|
||||
ATHROW
|
||||
LABEL (L8)
|
||||
LABEL (L7)
|
||||
}
|
||||
|
||||
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)
|
||||
ICONST_0
|
||||
ISTORE (4)
|
||||
ICONST_0
|
||||
ISTORE (5)
|
||||
ACONST_NULL
|
||||
ASTORE (5)
|
||||
ACONST_NULL
|
||||
ASTORE (6)
|
||||
ACONST_NULL
|
||||
ASTORE (7)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
ANEWARRAY
|
||||
INVOKEINTERFACE (kotlinx/serialization/Decoder, beginStructure, (Lkotlinx/serialization/SerialDescriptor;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/CompositeDecoder;)
|
||||
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)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
@@ -710,53 +743,48 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
ISTORE (3)
|
||||
ILOAD (3)
|
||||
TABLESWITCH
|
||||
LABEL (L2)
|
||||
ICONST_1
|
||||
ISTORE (4)
|
||||
LABEL (L3)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||
ASTORE (6)
|
||||
ILOAD (5)
|
||||
ASTORE (5)
|
||||
ILOAD (4)
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
ILOAD (4)
|
||||
IFEQ (L1)
|
||||
ISTORE (4)
|
||||
GOTO (L1)
|
||||
LABEL (L4)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_1
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, decodeStringElement, (Lkotlinx/serialization/SerialDescriptor;I)Ljava/lang/String;)
|
||||
ASTORE (7)
|
||||
ILOAD (5)
|
||||
ASTORE (6)
|
||||
ILOAD (4)
|
||||
ICONST_2
|
||||
IOR
|
||||
ISTORE (5)
|
||||
ILOAD (4)
|
||||
IFEQ (L1)
|
||||
LABEL (L5)
|
||||
ISTORE (4)
|
||||
GOTO (L1)
|
||||
LABEL (L2)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
INVOKEINTERFACE (kotlinx/serialization/CompositeDecoder, endStructure, (Lkotlinx/serialization/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (5)
|
||||
ILOAD (4)
|
||||
ALOAD (5)
|
||||
ALOAD (6)
|
||||
ALOAD (7)
|
||||
ACONST_NULL
|
||||
INVOKESPECIAL (User, <init>, (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L6)
|
||||
LABEL (L5)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (3)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
CHECKCAST
|
||||
ATHROW
|
||||
LABEL (L7)
|
||||
LABEL (L6)
|
||||
}
|
||||
|
||||
public java.lang.Object deserialize(kotlinx.serialization.Decoder p0) {
|
||||
|
||||
Reference in New Issue
Block a user