Skip to content

Commit 3b3f152

Browse files
committed
added logic for adding ClassTypeParamCount; added InvokeReturn, InstrTypeArg correctly
1 parent 60925ac commit 3b3f152

File tree

5 files changed

+70
-25
lines changed

5 files changed

+70
-25
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -775,14 +775,20 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
775775
stack.push(superQualTK)
776776
genLoadArguments(args, paramTKs(app))
777777
stack.pop()
778-
generatedType = genCallMethod(fun.symbol, InvokeStyle.Super, app.span)
778+
val invokeReturnType = app.getAttachment(InvokeReturnType)
779+
assert (invokeReturnType == None, s"Unexpected InvokeReturnType attachment on super call: $invokeReturnType")
780+
val instrTypeArgs = app.getAttachment(InstructionTypeArguments)
781+
// println("Super:" + fun)
782+
// println(s"DEBUG: Super($superQual), invokeReturnType = $invokeReturnType, instrTypeArgs = $instrTypeArgs")
783+
generatedType = genCallMethod(fun.symbol, InvokeStyle.Super, app.span, invokeReturnType = invokeReturnType,
784+
instrTypeArgs = instrTypeArgs)
779785

780786
// 'new' constructor call: Note: since constructors are
781787
// thought to return an instance of what they construct,
782788
// we have to 'simulate' it by DUPlicating the freshly created
783789
// instance (on JVM, <init> methods return VOID).
784790
case Apply(fun @ DesugaredSelect(New(tpt), nme.CONSTRUCTOR), args) =>
785-
println(s"DEBUG: New(tpt = $tpt) at ${app.span}")
791+
// println(s"DEBUG: New(tpt = $tpt) at ${app.span}")
786792
val ctor = fun.symbol
787793
assert(ctor.isClassConstructor, s"'new' call to non-constructor: ${ctor.name}")
788794

@@ -879,11 +885,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
879885
defn.ObjectClass
880886
} else qualSym
881887
}
882-
// println("GenApply.case Apply:" + fun)
883-
// println(s" returnType: ${app.getAttachment(InvokeReturnType)} InstructionTypeArg: ${fun.getAttachment(InstructionTypeArguments)}")
888+
// println("GenApply.case Apply for " + sym + " in " + sym.owner)
889+
// println(s"--fun: $fun, attachments: ${fun.getAttachment(InvokeReturnType)} : ${fun.getAttachment(InstructionTypeArguments)}")
890+
// println(s"--app: $app, attachments: ${app.getAttachment(InvokeReturnType)} : ${app.getAttachment(InstructionTypeArguments)}")
891+
val invokeReturnType = fun.getAttachment(InvokeReturnType) match {
892+
case None => app.getAttachment(InvokeReturnType)
893+
case some => some
894+
}
895+
val instrTypeArgs = fun.getAttachment(InstructionTypeArguments) match {
896+
case None => app.getAttachment(InstructionTypeArguments)
897+
case some => some
898+
}
899+
//println(s"--returnType: ${app.getAttachment(InvokeReturnType)} InstructionTypeArg: ${fun.getAttachment(InstructionTypeArguments)}")
884900
// InvokeReturnType, InstructionTypeArguments are fetched here
885-
generatedType = genCallMethod(sym, invokeStyle, app.span, receiverClass,
886-
app.getAttachment(InvokeReturnType), fun.getAttachment(InstructionTypeArguments))
901+
generatedType = genCallMethod(sym, invokeStyle, app.span, receiverClass,
902+
invokeReturnType, instrTypeArgs)
887903
}
888904
}
889905
}
@@ -1464,9 +1480,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
14641480
bmType.argumentTypes.copyToArray(args, 1)
14651481
val staticDesc = MethodBType(ownerBType :: bmType.argumentTypes, bmType.returnType).descriptor
14661482
val staticName = traitSuperAccessorName(method)
1467-
bc.invokestatic(receiverName, staticName, staticDesc, isInterface)
1483+
bc.invokestatic(receiverName, staticName, staticDesc, isInterface, invokeReturnType, instrTypeArgs)
14681484
} else {
1469-
bc.invokespecial(receiverName, jname, mdescr, isInterface)
1485+
bc.invokespecial(receiverName, jname, mdescr, isInterface, invokeReturnType, instrTypeArgs)
14701486
}
14711487
} else {
14721488
val opc = style match {

compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions
4040
import dotty.tools.backend.jvm.attributes.MethodTypeParameterCount
4141
import dotty.tools.backend.jvm.attributes.MethodReturnType
4242
import dotty.tools.backend.jvm.attributes.MethodParameterType
43+
import dotty.tools.backend.jvm.attributes.FieldType
4344
import dotty.tools.backend.jvm.attributes.TypeHints
4445

4546
/*
@@ -255,7 +256,8 @@ trait BCodeHelpers extends BCodeIdiomatic {
255256

256257
def addMethodParameterTypeAttribute(mw: asm.MethodVisitor, lst: List[dotty.tools.dotc.transform.TypeB]) : Unit =
257258
if (lst.isEmpty) return
258-
val lstJTypeB = lst.map(toJTypeB)
259+
val lstJTypeB = lst.filter(_ != dotty.tools.dotc.transform.TypeB.None).map(toJTypeB)
260+
if (lstJTypeB.isEmpty) return
259261
val len = lstJTypeB.length
260262
val attr = new MethodParameterType(len, lstJTypeB.asJava)
261263
mw.visitAttribute(attr)
@@ -274,13 +276,18 @@ trait BCodeHelpers extends BCodeIdiomatic {
274276
/*
275277
* must-single-thread
276278
*/
277-
def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation]): Unit =
279+
def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], attr: Option[(Int, List[dotty.tools.dotc.transform.TypeB], dotty.tools.dotc.transform.TypeB)]): Unit =
278280
for(annot <- annotations; if shouldEmitAnnotation(annot)) {
279281
val typ = annot.tree.tpe
280282
val assocs = assocsFromApply(annot.tree)
281283
val av = fw.visitAnnotation(typeDescriptor(typ), isRuntimeVisible(annot))
282284
emitAssocs(av, assocs, BCodeHelpers.this)(this)
283285
}
286+
attr match
287+
case None => ()
288+
case Some((count, paramTypeB, returnTypeB)) =>
289+
assert (count == 0 && paramTypeB.isEmpty)
290+
fw.visitAttribute(new FieldType(toJTypeB(returnTypeB)))
284291

285292
/*
286293
* must-single-thread

compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -410,20 +410,28 @@ trait BCodeIdiomatic {
410410
final def rem(tk: BType): Unit = { emitPrimitive(JCodeMethodN.remOpcodes, tk) } // can-multi-thread
411411

412412
// can-multi-thread
413-
final def invokespecial(owner: String, name: String, desc: String, itf: Boolean): Unit = {
414-
emitInvoke(Opcodes.INVOKESPECIAL, owner, name, desc, itf)
413+
final def invokespecial(owner: String, name: String, desc: String, itf: Boolean,
414+
invokeReturnType : Option[dotty.tools.dotc.transform.TypeB] = None, instrTypeArgs : Option[List[dotty.tools.dotc.transform.TypeA]] = None
415+
): Unit = {
416+
emitInvoke(Opcodes.INVOKESPECIAL, owner, name, desc, itf, invokeReturnType = invokeReturnType, instrTypeArgs = instrTypeArgs)
415417
}
416418
// can-multi-thread
417-
final def invokestatic(owner: String, name: String, desc: String, itf: Boolean): Unit = {
418-
emitInvoke(Opcodes.INVOKESTATIC, owner, name, desc, itf)
419+
final def invokestatic(owner: String, name: String, desc: String, itf: Boolean,
420+
invokeReturnType : Option[dotty.tools.dotc.transform.TypeB] = None, instrTypeArgs : Option[List[dotty.tools.dotc.transform.TypeA]] = None
421+
): Unit = {
422+
emitInvoke(Opcodes.INVOKESTATIC, owner, name, desc, itf, invokeReturnType = invokeReturnType, instrTypeArgs = instrTypeArgs)
419423
}
420424
// can-multi-thread
421-
final def invokeinterface(owner: String, name: String, desc: String): Unit = {
422-
emitInvoke(Opcodes.INVOKEINTERFACE, owner, name, desc, itf = true)
425+
final def invokeinterface(owner: String, name: String, desc: String,
426+
invokeReturnType : Option[dotty.tools.dotc.transform.TypeB] = None, instrTypeArgs : Option[List[dotty.tools.dotc.transform.TypeA]] = None
427+
): Unit = {
428+
emitInvoke(Opcodes.INVOKEINTERFACE, owner, name, desc, itf = true, invokeReturnType = invokeReturnType, instrTypeArgs = instrTypeArgs)
423429
}
424430
// can-multi-thread
425-
final def invokevirtual(owner: String, name: String, desc: String): Unit = {
426-
emitInvoke(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf = false)
431+
final def invokevirtual(owner: String, name: String, desc: String,
432+
invokeReturnType : Option[dotty.tools.dotc.transform.TypeB] = None, instrTypeArgs : Option[List[dotty.tools.dotc.transform.TypeA]] = None
433+
): Unit = {
434+
emitInvoke(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf = false, invokeReturnType = invokeReturnType, instrTypeArgs = instrTypeArgs)
427435
}
428436

429437
def toJTypeB(tpe: dotty.tools.dotc.transform.TypeB): TypeHints.TypeB =

compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import dotty.tools.dotc.util.Spans.*
2222
import dotty.tools.dotc.report
2323
import dotty.tools.dotc.transform.ErasedInfo
2424
import dotty.tools.dotc.transform.MethodParameterReturnType
25+
import dotty.tools.backend.jvm.attributes.*
2526

2627

2728
/*
@@ -291,7 +292,21 @@ trait BCodeSkelBuilder extends BCodeHelpers {
291292
}
292293
if (optSerial.isDefined) { addSerialVUID(optSerial.get, cnode)}
293294

294-
addClassFields()
295+
val templ = cd.rhs.asInstanceOf[Template]
296+
val classTypeParamCnt =
297+
templ.constr.getAttachment(MethodParameterReturnType) match
298+
case None => 0
299+
case Some(cnt, _, _) => cnt
300+
// println(s"Class ${claszSymbol} has ${classTypeParamCnt} type parameters")
301+
if (classTypeParamCnt > 0) cnode.visitAttribute(new ClassTypeParameterCount(classTypeParamCnt))
302+
var fieldAttrs: Map[Symbol, (Int, List[dotty.tools.dotc.transform.TypeB], dotty.tools.dotc.transform.TypeB)] = Map.empty
303+
fieldAttrs =
304+
templ.body.collect {
305+
case vd: tpd.ValDef =>
306+
vd.getAttachment(MethodParameterReturnType).map(v => vd.symbol -> v)
307+
}.flatten.toMap
308+
309+
addClassFields(fieldAttrs)
295310
gen(cd.rhs)
296311

297312
if (AsmUtils.traceClassEnabled && cnode.name.contains(AsmUtils.traceClassPattern))
@@ -393,16 +408,15 @@ trait BCodeSkelBuilder extends BCodeHelpers {
393408
clinit.visitEnd()
394409
}
395410

396-
def addClassFields(): Unit = {
411+
def addClassFields(fieldAttrs: Map[Symbol, (Int, List[dotty.tools.dotc.transform.TypeB], dotty.tools.dotc.transform.TypeB)] = Map.empty): Unit = {
397412
/* Non-method term members are fields, except for module members. Module
398413
* members can only happen on .NET (no flatten) for inner traits. There,
399414
* a module symbol is generated (transformInfo in mixin) which is used
400415
* as owner for the members of the implementation class (so that the
401416
* backend emits them as static).
402417
* No code is needed for this module symbol.
403418
*/
404-
// println("for class " + claszSymbol + " adding fields:")
405-
// println("has methods:" + claszSymbol.info.decls.filter(p => p.is(Method)).toList)
419+
// println("for class " + claszSymbol + " adding fields attrs:" + fieldAttrs)
406420
for (f <- claszSymbol.info.decls.filter(p => p.isTerm && !p.is(Method))) {
407421
val javagensig = getGenericSignature(f, claszSymbol)
408422
val flags = javaFieldFlags(f)
@@ -418,8 +432,8 @@ trait BCodeSkelBuilder extends BCodeHelpers {
418432
null // no initial value
419433
)
420434
cnode.fields.add(jfield)
421-
// println("Adding field:" + f + " to " + claszSymbol + "with annotations " + f.annotations)
422-
emitAnnotations(jfield, f.annotations)
435+
// println("Adding field:" + f + " to " + claszSymbol + " with annotations " + fieldAttrs.get(f))
436+
emitAnnotations(jfield, f.annotations, fieldAttrs.get(f))
423437
}
424438

425439
} // end of method addClassFields()

compiler/src/dotty/tools/backend/jvm/attributes/ClassTypeParameterCount.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public boolean isUnknown() {
3333
@Override
3434
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
3535
int localCount = cr.readUnsignedShort(off);
36-
return new MethodTypeParameterCount(localCount);
36+
return new ClassTypeParameterCount(localCount);
3737
}
3838

3939
@Override

0 commit comments

Comments
 (0)