@@ -72,12 +72,12 @@ object Semantic {
72
72
def outer : Value
73
73
def objekt (using Heap ): Objekt = heap(this )
74
74
75
- def ensureObjectExists ()(using Heap ) =
76
- if heap.contains(this ) then heap( this )
75
+ def ensureObjectExists ()(using Heap ): this . type =
76
+ if heap.contains(this ) then this
77
77
else {
78
78
val obj = Objekt (this .klass, fields = Map .empty, outers = Map (this .klass -> this .outer))
79
79
heap.update(this , obj)
80
- obj
80
+ this
81
81
}
82
82
83
83
@@ -113,6 +113,22 @@ object Semantic {
113
113
*/
114
114
case class Warm (klass : ClassSymbol , outer : Value , ctor : Symbol , args : List [Value ])(using @ constructorOnly h : Heap ) extends Ref {
115
115
ensureObjectExists()
116
+
117
+ /** Ensure that outers and class parameters are initialized.
118
+ *
119
+ * Fields in class body are not initialized.
120
+ */
121
+ def ensureInit (): Contextual [this .type ] =
122
+ // Somehow Dotty uses the one in the class parameters
123
+ given Heap = state.heap
124
+ if objekt.outers.size <= 1 then
125
+ val tpl = klass.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
126
+ val termParamss = ctor.defTree.asInstanceOf [DefDef ].termParamss
127
+ val paramValues = termParamss.flatten.zip(args).map((param, v) => param.symbol -> v).toMap
128
+ given Env = Env (paramValues)
129
+ init(tpl, this , klass)
130
+ end if
131
+ this
116
132
}
117
133
118
134
/** A function value */
@@ -292,12 +308,13 @@ object Semantic {
292
308
if current.contains(value, expr) then current(value)(expr)
293
309
else stable(value)(expr)
294
310
295
- def assume (value : Value , expr : Tree , cacheResult : Boolean )(fun : => Result )( using Heap ) : Result =
311
+ def assume (value : Value , expr : Tree , cacheResult : Boolean )(fun : => Result ): Contextual [ Result ] =
296
312
val assumeValue : Value =
297
313
if last.contains(value, expr) then
298
314
// Due to heap reverting, the object corresponding to a reference may not exist in the heap.
299
315
last.get(value, expr) match
300
- case ref : Ref => ref.ensureObjectExists(); ref
316
+ case ref : ThisRef => ref.ensureObjectExists()
317
+ case ref : Warm => ref.ensureObjectExists().ensureInit()
301
318
case v => v
302
319
else
303
320
last.put(value, expr, Hot )
@@ -395,6 +412,8 @@ object Semantic {
395
412
given (using s : State ): Cache = s.cache
396
413
given (using s : State ): WorkList = s.workList
397
414
415
+ inline def state (using s : State ) = s
416
+
398
417
/** The state that threads through the interpreter */
399
418
type Contextual [T ] = (Env , Context , Trace , Promoted , State ) ?=> T
400
419
@@ -631,12 +650,11 @@ object Semantic {
631
650
Result (Hot , Errors .empty)
632
651
else
633
652
val outer = Hot
634
- val warm = Warm (klass, outer, ctor, args2)
653
+ val warm = Warm (klass, outer, ctor, args2).ensureInit()
635
654
val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
636
- val res = warm.callConstructor(ctor, argInfos2, source)
637
655
val task = ThisRef (klass, outer, ctor, args2)
638
656
this .addTask(task)
639
- Result (warm, res.errors )
657
+ Result (warm, Errors .empty )
640
658
641
659
case Cold =>
642
660
val error = CallCold (ctor, source, trace1.toVector)
@@ -651,11 +669,10 @@ object Semantic {
651
669
652
670
val argsWidened = args.map(_.value).widenArgs
653
671
val argInfos2 = args.zip(argsWidened).map { (argInfo, v) => argInfo.copy(value = v) }
654
- val warm = Warm (klass, outer, ctor, argsWidened)
655
- val res = warm.callConstructor(ctor, argInfos2, source)
672
+ val warm = Warm (klass, outer, ctor, argsWidened).ensureInit()
656
673
val task = ThisRef (klass, outer, ctor, argsWidened)
657
674
this .addTask(task)
658
- Result (warm, res.errors )
675
+ Result (warm, Errors .empty )
659
676
660
677
case Fun (body, thisV, klass, env) =>
661
678
report.error(" unexpected tree in instantiating a function, fun = " + body.show, source)
@@ -1280,7 +1297,7 @@ object Semantic {
1280
1297
thisV.updateOuter(cls, res.value)
1281
1298
1282
1299
// follow constructor
1283
- if cls.hasSource && ! thisV.isWarm then
1300
+ if cls.hasSource then
1284
1301
tasks.append { () =>
1285
1302
printer.println(" init super class " + cls.show)
1286
1303
val res2 = thisV.callConstructor(ctor, args, source)
0 commit comments