@@ -105,11 +105,46 @@ class Semantic {
105105 *
106106 * This is only one object we need to care about, hence it's just `Objekt`.
107107 */
108- type Heap = mutable.Map [Addr , Objekt ]
108+ object Heap {
109+ opaque type Heap = mutable.Map [Addr , Objekt ]
110+
111+ /** Note: don't use `val` to avoid incorrect sharing */
112+ def empty : Heap = mutable.Map .empty
113+
114+ extension (heap : Heap )
115+ def apply (addr : Addr ): Objekt = heap(addr)
116+ def add (addr : Addr , obj : Objekt ): Unit = heap(addr) = obj
117+ end extension
118+
119+ extension (ref : Addr )
120+ def updateField (field : Symbol , value : Value ): Contextual [Unit ] =
121+ heap(ref).fields(field) = value
122+
123+ def updateOuter (klass : ClassSymbol , value : Value ): Contextual [Unit ] =
124+ heap(ref).outers(klass) = value
125+ end extension
126+ }
127+ type Heap = Heap .Heap
128+
129+ import Heap ._
109130 def heap (using h : Heap ): Heap = h
110131
111- /** Values that have been safely promoted */
112- type Promoted = mutable.Set [Value ]
132+ object Promoted {
133+ /** Values that have been safely promoted */
134+ opaque type Promoted = mutable.Set [Value ]
135+
136+ /** Note: don't use `val` to avoid incorrect sharing */
137+ def empty : Promoted = mutable.Set .empty
138+
139+ extension (promoted : Promoted )
140+ def contains (value : Value ): Boolean = promoted.contains(value)
141+ def add (value : Value ): Unit = promoted += value
142+ def remove (value : Value ): Unit = promoted -= value
143+ end extension
144+ }
145+ type Promoted = Promoted .Promoted
146+
147+ import Promoted ._
113148 def promoted (using p : Promoted ): Promoted = p
114149
115150 /** Interpreter configuration
@@ -171,11 +206,21 @@ class Semantic {
171206 type Contextual [T ] = (Heap , Context , Trace , Promoted ) ?=> T
172207
173208// ----- Error Handling -----------------------------------
174- type Trace = Vector [Tree ]
175- def trace (using t : Trace ): Trace = t
176209
177- extension (trace : Trace )
178- def add (node : Tree ): Trace = trace :+ node
210+ object Trace {
211+ opaque type Trace = Vector [Tree ]
212+
213+ val empty : Trace = Vector .empty
214+
215+ extension (trace : Trace )
216+ def add (node : Tree ): Trace = trace :+ node
217+ def toVector : Vector [Tree ] = trace
218+ }
219+
220+ type Trace = Trace .Trace
221+
222+ import Trace ._
223+ def trace (using t : Trace ): Trace = t
179224
180225// ----- Operations on domains -----------------------------
181226 extension (a : Value )
@@ -209,7 +254,7 @@ class Semantic {
209254 Result (Hot , Errors .empty)
210255
211256 case Cold =>
212- val error = AccessCold (field, source, trace)
257+ val error = AccessCold (field, source, trace.toVector )
213258 Result (Hot , error :: Nil )
214259
215260 case addr : Addr =>
@@ -225,10 +270,10 @@ class Semantic {
225270 val rhs = target.defTree.asInstanceOf [ValOrDefDef ].rhs
226271 eval(rhs, addr, target.owner.asClass, cacheResult = true )
227272 else
228- val error = CallUnknown (field, source, trace)
273+ val error = CallUnknown (field, source, trace.toVector )
229274 Result (Hot , error :: Nil )
230275 else
231- val error = AccessNonInit (target, trace.add(source))
276+ val error = AccessNonInit (target, trace.add(source).toVector )
232277 Result (Hot , error :: Nil )
233278
234279 case _ : Fun =>
@@ -247,7 +292,7 @@ class Semantic {
247292 Result (Hot , Errors .empty)
248293
249294 case Cold =>
250- val error = CallCold (meth, source, trace)
295+ val error = CallCold (meth, source, trace.toVector )
251296 Result (Hot , error :: Nil )
252297
253298 case addr : Addr =>
@@ -270,7 +315,7 @@ class Semantic {
270315 else if addr.canIgnoreMethodCall(target) then
271316 Result (Hot , Nil )
272317 else
273- val error = CallUnknown (target, source, trace)
318+ val error = CallUnknown (target, source, trace.toVector )
274319 Result (Hot , error :: Nil )
275320 else
276321 val obj = heap(addr)
@@ -298,7 +343,7 @@ class Semantic {
298343 Result (Hot , Errors .empty)
299344
300345 case Cold =>
301- val error = CallCold (ctor, source, trace)
346+ val error = CallCold (ctor, source, trace.toVector )
302347 Result (Hot , error :: Nil )
303348
304349 case thisRef : ThisRef =>
@@ -324,14 +369,6 @@ class Semantic {
324369 }
325370 end extension
326371
327- extension (ref : Addr )
328- def updateField (field : Symbol , value : Value ): Contextual [Unit ] =
329- heap(ref).fields(field) = value
330-
331- def updateOuter (klass : ClassSymbol , value : Value ): Contextual [Unit ] =
332- heap(ref).outers(klass) = value
333- end extension
334-
335372// ----- Promotion ----------------------------------------------------
336373
337374 extension (value : Value )
@@ -349,7 +386,7 @@ class Semantic {
349386
350387 case warm : Warm =>
351388 warm.outer.canPromoteExtrinsic && {
352- promoted += warm
389+ promoted.add( warm)
353390 true
354391 }
355392
@@ -361,13 +398,13 @@ class Semantic {
361398 val sym = denot.symbol
362399 sym.isOneOf(Flags .Lazy | Flags .Deferred ) || obj.fields.contains(sym)
363400 }
364- if allFieldsInitialized then promoted += thisRef
401+ if allFieldsInitialized then promoted.add( thisRef)
365402 allFieldsInitialized
366403 }
367404
368405 case fun : Fun =>
369406 fun.thisV.canPromoteExtrinsic && {
370- promoted += fun
407+ promoted.add( fun)
371408 true
372409 }
373410
@@ -381,20 +418,20 @@ class Semantic {
381418 value match
382419 case Hot => Nil
383420
384- case Cold => PromoteError (msg, source, trace) :: Nil
421+ case Cold => PromoteError (msg, source, trace.toVector ) :: Nil
385422
386423 case thisRef : ThisRef =>
387424 if promoted.contains(thisRef) then Nil
388425 else if thisRef.canPromoteExtrinsic then Nil
389- else PromoteError (msg, source, trace) :: Nil
426+ else PromoteError (msg, source, trace.toVector ) :: Nil
390427
391428 case warm : Warm =>
392429 if promoted.contains(warm) then Nil
393430 else if warm.canPromoteExtrinsic then Nil
394431 else {
395- promoted += warm
432+ promoted.add( warm)
396433 val errors = warm.tryPromote(msg, source)
397- if errors.nonEmpty then promoted -= warm
434+ if errors.nonEmpty then promoted.remove( warm)
398435 errors
399436 }
400437
@@ -404,9 +441,9 @@ class Semantic {
404441 val res = eval(body, thisV, klass)
405442 val errors2 = res.value.promote(msg, source)
406443 if (res.errors.nonEmpty || errors2.nonEmpty)
407- UnsafePromotion (msg, source, trace, res.errors ++ errors2) :: Nil
444+ UnsafePromotion (msg, source, trace.toVector , res.errors ++ errors2) :: Nil
408445 else
409- promoted += fun
446+ promoted.add( fun)
410447 Nil
411448
412449 case RefSet (refs) =>
@@ -434,7 +471,7 @@ class Semantic {
434471 def tryPromote (msg : String , source : Tree ): Contextual [List [Error ]] = log(" promote " + warm.show, printer) {
435472 val classRef = warm.klass.appliedRef
436473 if classRef.memberClasses.nonEmpty then
437- return PromoteError (msg, source, trace) :: Nil
474+ return PromoteError (msg, source, trace.toVector ) :: Nil
438475
439476 val fields = classRef.fields
440477 val methods = classRef.membersBasedOnFlags(Flags .Method , Flags .Deferred | Flags .Accessor )
@@ -465,7 +502,7 @@ class Semantic {
465502 }
466503
467504 if buffer.isEmpty then Nil
468- else UnsafePromotion (msg, source, trace, buffer.toList) :: Nil
505+ else UnsafePromotion (msg, source, trace.toVector , buffer.toList) :: Nil
469506 }
470507
471508 end extension
0 commit comments