Names from new runtime

This commit is contained in:
Leonid Startsev
2018-05-21 19:42:57 +03:00
parent 223733558c
commit edcac21723
5 changed files with 38 additions and 37 deletions
@@ -123,9 +123,9 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
unsubstitutedMemberScope.getDescriptorsFiltered { it == Name.identifier(funcName) } unsubstitutedMemberScope.getDescriptorsFiltered { it == Name.identifier(funcName) }
override fun generateSave(function: FunctionDescriptor) = generateFunction(function) { jsFun, ctx -> override fun generateSave(function: FunctionDescriptor) = generateFunction(function) { jsFun, ctx ->
val kOutputClass = serializerDescriptor.getClassFromSerializationPackage("KOutput") val kOutputClass = serializerDescriptor.getClassFromSerializationPackage("StructureEncoder")
val wBeginFunc = ctx.getNameForDescriptor( val wBeginFunc = ctx.getNameForDescriptor(
kOutputClass.getFuncDesc("writeBegin").single { (it as FunctionDescriptor).valueParameters.size == 2 }) kOutputClass.getFuncDesc("beginStructure").single { (it as FunctionDescriptor).valueParameters.size == 2 })
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef()) val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef())
// output.writeBegin(desc, []) // output.writeBegin(desc, [])
@@ -151,7 +151,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
val innerSerial = serializerInstance(sti.serializer, property.module, property.type, property.genericIndex) val innerSerial = serializerInstance(sti.serializer, property.module, property.type, property.genericIndex)
if (innerSerial == null) { if (innerSerial == null) {
val writeFunc = val writeFunc =
kOutputClass.getFuncDesc("write${sti.elementMethodPrefix}ElementValue").single() kOutputClass.getFuncDesc("encode${sti.elementMethodPrefix}ElementValue").single()
.let { ctx.getNameForDescriptor(it) } .let { ctx.getNameForDescriptor(it) }
+JsInvocation(JsNameRef(writeFunc, localOutputRef), +JsInvocation(JsNameRef(writeFunc, localOutputRef),
serialClassDescRef, serialClassDescRef,
@@ -160,7 +160,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
} }
else { else {
val writeFunc = val writeFunc =
kOutputClass.getFuncDesc("write${sti.elementMethodPrefix}SerializableElementValue").single() kOutputClass.getFuncDesc("encode${sti.elementMethodPrefix}SerializableElementValue").single()
.let { ctx.getNameForDescriptor(it) } .let { ctx.getNameForDescriptor(it) }
+JsInvocation(JsNameRef(writeFunc, localOutputRef), +JsInvocation(JsNameRef(writeFunc, localOutputRef),
serialClassDescRef, serialClassDescRef,
@@ -171,7 +171,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
} }
// output.writeEnd(serialClassDesc) // output.writeEnd(serialClassDesc)
val wEndFunc = kOutputClass.getFuncDesc("writeEnd").single() val wEndFunc = kOutputClass.getFuncDesc("endStructure").single()
.let { ctx.getNameForDescriptor(it) } .let { ctx.getNameForDescriptor(it) }
+JsInvocation(JsNameRef(wEndFunc, localOutputRef), serialClassDescRef).makeStmt() +JsInvocation(JsNameRef(wEndFunc, localOutputRef), serialClassDescRef).makeStmt()
} }
@@ -212,7 +212,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
override fun generateLoad(function: FunctionDescriptor) = generateFunction(function) { jsFun, context -> override fun generateLoad(function: FunctionDescriptor) = generateFunction(function) { jsFun, context ->
val inputClass = serializerDescriptor.getClassFromSerializationPackage("KInput") val inputClass = serializerDescriptor.getClassFromSerializationPackage("StructureDecoder")
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef()) val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef())
// var index = -1, readAll = false // var index = -1, readAll = false
@@ -237,7 +237,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef()) JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef())
} }
val inputVar = JsNameRef(jsFun.scope.declareFreshName("input")) val inputVar = JsNameRef(jsFun.scope.declareFreshName("input"))
val readBeginF = inputClass.getFuncDesc("readBegin").single() val readBeginF = inputClass.getFuncDesc("beginStructure").single()
val call = JsInvocation(JsNameRef(context.getNameForDescriptor(readBeginF), JsNameRef(jsFun.parameters[0].name)), val call = JsInvocation(JsNameRef(context.getNameForDescriptor(readBeginF), JsNameRef(jsFun.parameters[0].name)),
serialClassDescRef, JsArrayLiteral(typeParams)) serialClassDescRef, JsArrayLiteral(typeParams))
+JsVars(JsVars.JsVar(inputVar.name, call)) +JsVars(JsVars.JsVar(inputVar.name, call))
@@ -247,7 +247,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
val loopRef = JsNameRef(loop.name) val loopRef = JsNameRef(loop.name)
jsWhile(JsBooleanLiteral(true), { jsWhile(JsBooleanLiteral(true), {
// index = input.readElement(classDesc) // index = input.readElement(classDesc)
val readElementF = context.getNameForDescriptor(inputClass.getFuncDesc("readElement").single()) val readElementF = context.getNameForDescriptor(inputClass.getFuncDesc("decodeElement").single())
+JsAstUtils.assignment( +JsAstUtils.assignment(
indexVar, indexVar,
JsInvocation(JsNameRef(readElementF, inputVar), serialClassDescRef) JsInvocation(JsNameRef(readElementF, inputVar), serialClassDescRef)
@@ -270,7 +270,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
val call: JsExpression = if (innerSerial == null) { val call: JsExpression = if (innerSerial == null) {
val unknownSer = (sti.elementMethodPrefix.isEmpty()) val unknownSer = (sti.elementMethodPrefix.isEmpty())
val readFunc = val readFunc =
inputClass.getFuncDesc("read${sti.elementMethodPrefix}ElementValue") inputClass.getFuncDesc("decode${sti.elementMethodPrefix}ElementValue")
// if readElementValue, must have 3 parameters, if readXXXElementValue - 2 // if readElementValue, must have 3 parameters, if readXXXElementValue - 2
.single { !unknownSer || (it is FunctionDescriptor && it.valueParameters.size == 3) } .single { !unknownSer || (it is FunctionDescriptor && it.valueParameters.size == 3) }
.let { context.getNameForDescriptor(it) } .let { context.getNameForDescriptor(it) }
@@ -281,7 +281,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
else { else {
val notSeenTest = propNotSeenTest(bitMasks[i / 32], i) val notSeenTest = propNotSeenTest(bitMasks[i / 32], i)
val readFunc = val readFunc =
inputClass.getFuncDesc("read${sti.elementMethodPrefix}SerializableElementValue").single() inputClass.getFuncDesc("decode${sti.elementMethodPrefix}SerializableElementValue").single()
.let { context.getNameForDescriptor(it) } .let { context.getNameForDescriptor(it) }
val updateFunc = val updateFunc =
inputClass.getFuncDesc("update${sti.elementMethodPrefix}SerializableElementValue").single() inputClass.getFuncDesc("update${sti.elementMethodPrefix}SerializableElementValue").single()
@@ -349,7 +349,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
}, loop) }, loop)
// input.readEnd(desc) // input.readEnd(desc)
val readEndF = inputClass.getFuncDesc("readEnd").single() val readEndF = inputClass.getFuncDesc("endStructure").single()
.let { context.getNameForDescriptor(it) } .let { context.getNameForDescriptor(it) }
+JsInvocation( +JsInvocation(
JsNameRef(readEndF, inputVar), JsNameRef(readEndF, inputVar),
@@ -34,14 +34,14 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescripto
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
internal val descType = Type.getObjectType("kotlinx/serialization/KSerialClassDesc") internal val descType = Type.getObjectType("kotlinx/serialization/SerialDescriptor")
internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/SerialClassDescImpl") internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/SerialClassDescImpl")
internal val kOutputType = Type.getObjectType("kotlinx/serialization/KOutput") internal val kOutputType = Type.getObjectType("kotlinx/serialization/StructureEncoder")
internal val kInputType = Type.getObjectType("kotlinx/serialization/KInput") internal val kInputType = Type.getObjectType("kotlinx/serialization/StructureDecoder")
internal val kSerialSaverType = Type.getObjectType("kotlinx/serialization/KSerialSaver") internal val kSerialSaverType = Type.getObjectType("kotlinx/serialization/SerializationStrategy")
internal val kSerialLoaderType = Type.getObjectType("kotlinx/serialization/KSerialLoader") internal val kSerialLoaderType = Type.getObjectType("kotlinx/serialization/DeserializationStrategy")
internal val kSerializerType = Type.getObjectType("kotlinx/serialization/KSerializer") internal val kSerializerType = Type.getObjectType("kotlinx/serialization/KSerializer")
internal val kSerializerArrayType = Type.getObjectType("[Lkotlinx/serialization/KSerializer;") internal val kSerializerArrayType = Type.getObjectType("[Lkotlinx/serialization/KSerializer;")
@@ -77,11 +77,11 @@ fun InstructionAdapter.genKOutputMethodCall(property: SerializableProperty, clas
val useSerializer = if (fromClassStartVar == null) stackValueSerializerInstanceFromSerializer(classCodegen, sti) val useSerializer = if (fromClassStartVar == null) stackValueSerializerInstanceFromSerializer(classCodegen, sti)
else stackValueSerializerInstanceFromClass(classCodegen, sti, fromClassStartVar) else stackValueSerializerInstanceFromClass(classCodegen, sti, fromClassStartVar)
if (!sti.unit) classCodegen.genPropertyOnStack(this, expressionCodegen.context, property.descriptor, propertyOwnerType, ownerVar) if (!sti.unit) classCodegen.genPropertyOnStack(this, expressionCodegen.context, property.descriptor, propertyOwnerType, ownerVar)
invokevirtual(kOutputType.internalName, invokeinterface(kOutputType.internalName,
"write" + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + "ElementValue", "encode" + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + "ElementValue",
"(" + descType.descriptor + "I" + "(" + descType.descriptor + "I" +
(if (useSerializer) kSerialSaverType.descriptor else "") + (if (useSerializer) kSerialSaverType.descriptor else "") +
(if (sti.unit) "" else sti.type.descriptor) + ")V", false) (if (sti.unit) "" else sti.type.descriptor) + ")V")
} }
internal fun InstructionAdapter.buildInternalConstructorDesc(propsStartVar: Int, bitMaskBase: Int, codegen: ClassBodyCodegen, args: List<SerializableProperty>): String { internal fun InstructionAdapter.buildInternalConstructorDesc(propsStartVar: Int, bitMaskBase: Int, codegen: ClassBodyCodegen, args: List<SerializableProperty>): String {
@@ -155,9 +155,9 @@ class SerializerCodegenImpl(
load(outputVar, kOutputType) load(outputVar, kOutputType)
load(descVar, descType) load(descVar, descType)
genArrayOfTypeParametersSerializers() genArrayOfTypeParametersSerializers()
invokevirtual(kOutputType.internalName, "writeBegin", invokeinterface(kOutputType.internalName, "beginStructure",
"(" + descType.descriptor + kSerializerArrayType.descriptor + "(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kOutputType.descriptor, false) ")" + kOutputType.descriptor)
store(outputVar, kOutputType) store(outputVar, kOutputType)
if (serializableDescriptor.isInternalSerializable) { if (serializableDescriptor.isInternalSerializable) {
val sig = StringBuilder("(${kOutputType.descriptor}${descType.descriptor}") val sig = StringBuilder("(${kOutputType.descriptor}${descType.descriptor}")
@@ -190,8 +190,8 @@ class SerializerCodegenImpl(
// output.writeEnd(classDesc) // output.writeEnd(classDesc)
load(outputVar, kOutputType) load(outputVar, kOutputType)
load(descVar, descType) load(descVar, descType)
invokevirtual(kOutputType.internalName, "writeEnd", invokeinterface(kOutputType.internalName, "endStructure",
"(" + descType.descriptor + ")V", false) "(" + descType.descriptor + ")V")
// return // return
areturn(Type.VOID_TYPE) areturn(Type.VOID_TYPE)
} }
@@ -245,17 +245,17 @@ class SerializerCodegenImpl(
load(inputVar, kInputType) load(inputVar, kInputType)
load(descVar, descType) load(descVar, descType)
genArrayOfTypeParametersSerializers() genArrayOfTypeParametersSerializers()
invokevirtual(kInputType.internalName, "readBegin", invokeinterface(kInputType.internalName, "beginStructure",
"(" + descType.descriptor + kSerializerArrayType.descriptor + "(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kInputType.descriptor, false) ")" + kInputType.descriptor)
store(inputVar, kInputType) store(inputVar, kInputType)
// readElement: int index = input.readElement(classDesc) // readElement: int index = input.readElement(classDesc)
val readElementLabel = Label() val readElementLabel = Label()
visitLabel(readElementLabel) visitLabel(readElementLabel)
load(inputVar, kInputType) load(inputVar, kInputType)
load(descVar, descType) load(descVar, descType)
invokevirtual(kInputType.internalName, "readElement", invokeinterface(kInputType.internalName, "decodeElement",
"(" + descType.descriptor + ")I", false) "(" + descType.descriptor + ")I")
store(indexVar, Type.INT_TYPE) store(indexVar, Type.INT_TYPE)
// switch(index) // switch(index)
val labeledProperties = orderedProperties.filter { !it.transient } val labeledProperties = orderedProperties.filter { !it.transient }
@@ -296,13 +296,13 @@ class SerializerCodegenImpl(
} }
fun produceCall(update: Boolean) { fun produceCall(update: Boolean) {
invokevirtual(kInputType.internalName, invokeinterface(kInputType.internalName,
(if (update) "update" else "read") + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + "ElementValue", (if (update) "update" else "decode") + sti.elementMethodPrefix + (if (useSerializer) "Serializable" else "") + "ElementValue",
"(" + descType.descriptor + "I" + "(" + descType.descriptor + "I" +
(if (useSerializer) kSerialLoaderType.descriptor else "") (if (useSerializer) kSerialLoaderType.descriptor else "")
+ (if (unknownSer) AsmTypes.K_CLASS_TYPE.descriptor else "") + (if (unknownSer) AsmTypes.K_CLASS_TYPE.descriptor else "")
+ (if (update) sti.type.descriptor else "") + (if (update) sti.type.descriptor else "")
+ ")" + (if (sti.unit) "V" else sti.type.descriptor), false) + ")" + (if (sti.unit) "V" else sti.type.descriptor))
} }
if (useSerializer) { if (useSerializer) {
@@ -351,8 +351,8 @@ class SerializerCodegenImpl(
visitLabel(readEndLabel) visitLabel(readEndLabel)
load(inputVar, kInputType) load(inputVar, kInputType)
load(descVar, descType) load(descVar, descType)
invokevirtual(kInputType.internalName, "readEnd", invokeinterface(kInputType.internalName, "endStructure",
"(" + descType.descriptor + ")V", false) "(" + descType.descriptor + ")V")
if (!serializableDescriptor.isInternalSerializable) { if (!serializableDescriptor.isInternalSerializable) {
//validate all required (constructor) fields //validate all required (constructor) fields
val nonThrowLabel = Label() val nonThrowLabel = Label()
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.descType
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.SERIALIZER_CLASS_NAME import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.SERIALIZER_CLASS_NAME
internal val packageFqName = FqName("kotlinx.serialization") internal val packageFqName = FqName("kotlinx.serialization")
@@ -192,7 +193,7 @@ fun getSerializableClassDescriptorBySerializer(serializerDescriptor: ClassDescri
} }
fun ClassDescriptor.checkSerializableClassPropertyResult(prop: PropertyDescriptor): Boolean = fun ClassDescriptor.checkSerializableClassPropertyResult(prop: PropertyDescriptor): Boolean =
prop.returnType!!.isSubtypeOf(getClassFromSerializationPackage("KSerialClassDesc").toSimpleType(false)) // todo: cache lookup prop.returnType!!.isSubtypeOf(getClassFromSerializationPackage("SerialDescriptor").toSimpleType(false)) // todo: cache lookup
// todo: serialization: do an actual check better that just number of parameters // todo: serialization: do an actual check better that just number of parameters
fun ClassDescriptor.checkSaveMethodParameters(parameters: List<ValueParameterDescriptor>): Boolean = fun ClassDescriptor.checkSaveMethodParameters(parameters: List<ValueParameterDescriptor>): Boolean =
@@ -39,8 +39,8 @@ import java.util.*
object KSerializerDescriptorResolver { object KSerializerDescriptorResolver {
val SERIAL_DESC_FIELD = "serialClassDesc" val SERIAL_DESC_FIELD = "serialClassDesc"
val SAVE = "save" val SAVE = "serialize"
val LOAD = "load" val LOAD = "deserialize"
val SERIALIZER_CLASS = "\$serializer" val SERIALIZER_CLASS = "\$serializer"
internal val typeArgPrefix = "typeSerial" internal val typeArgPrefix = "typeSerial"
@@ -379,7 +379,7 @@ object KSerializerDescriptorResolver {
i++, i++,
Annotations.EMPTY, Annotations.EMPTY,
Name.identifier("output"), Name.identifier("output"),
thisClass.getClassFromSerializationPackage("KOutput").toSimpleType(false), thisClass.getClassFromSerializationPackage("StructureEncoder").toSimpleType(false),
false, false,
false, false,
false, false,
@@ -393,7 +393,7 @@ object KSerializerDescriptorResolver {
i++, i++,
Annotations.EMPTY, Annotations.EMPTY,
Name.identifier("serialDesc"), Name.identifier("serialDesc"),
thisClass.getClassFromSerializationPackage("KSerialClassDesc").toSimpleType(false), thisClass.getClassFromSerializationPackage("SerialDescriptor").toSimpleType(false),
false, false,
false, false,
false, false,