@@ -72,12 +72,12 @@ object Semantic {
7272 def outer : Value
7373 def objekt (using Heap ): Objekt = heap(this )
7474
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
7777 else {
7878 val obj = Objekt (this .klass, fields = Map .empty, outers = Map (this .klass -> this .outer))
7979 heap.update(this , obj)
80- obj
80+ this
8181 }
8282
8383
@@ -113,6 +113,22 @@ object Semantic {
113113 */
114114 case class Warm (klass : ClassSymbol , outer : Value , ctor : Symbol , args : List [Value ])(using @ constructorOnly h : Heap ) extends Ref {
115115 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
116132 }
117133
118134 /** A function value */
@@ -292,12 +308,13 @@ object Semantic {
292308 if current.contains(value, expr) then current(value)(expr)
293309 else stable(value)(expr)
294310
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 ] =
296312 val assumeValue : Value =
297313 if last.contains(value, expr) then
298314 // Due to heap reverting, the object corresponding to a reference may not exist in the heap.
299315 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()
301318 case v => v
302319 else
303320 last.put(value, expr, Hot )
@@ -395,6 +412,8 @@ object Semantic {
395412 given (using s : State ): Cache = s.cache
396413 given (using s : State ): WorkList = s.workList
397414
415+ inline def state (using s : State ) = s
416+
398417 /** The state that threads through the interpreter */
399418 type Contextual [T ] = (Env , Context , Trace , Promoted , State ) ?=> T
400419
@@ -631,12 +650,11 @@ object Semantic {
631650 Result (Hot , Errors .empty)
632651 else
633652 val outer = Hot
634- val warm = Warm (klass, outer, ctor, args2)
653+ val warm = Warm (klass, outer, ctor, args2).ensureInit()
635654 val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
636- val res = warm.callConstructor(ctor, argInfos2, source)
637655 val task = ThisRef (klass, outer, ctor, args2)
638656 this .addTask(task)
639- Result (warm, res.errors )
657+ Result (warm, Errors .empty )
640658
641659 case Cold =>
642660 val error = CallCold (ctor, source, trace1.toVector)
@@ -651,11 +669,10 @@ object Semantic {
651669
652670 val argsWidened = args.map(_.value).widenArgs
653671 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()
656673 val task = ThisRef (klass, outer, ctor, argsWidened)
657674 this .addTask(task)
658- Result (warm, res.errors )
675+ Result (warm, Errors .empty )
659676
660677 case Fun (body, thisV, klass, env) =>
661678 report.error(" unexpected tree in instantiating a function, fun = " + body.show, source)
@@ -1280,7 +1297,7 @@ object Semantic {
12801297 thisV.updateOuter(cls, res.value)
12811298
12821299 // follow constructor
1283- if cls.hasSource && ! thisV.isWarm then
1300+ if cls.hasSource then
12841301 tasks.append { () =>
12851302 printer.println(" init super class " + cls.show)
12861303 val res2 = thisV.callConstructor(ctor, args, source)
0 commit comments