@@ -69,6 +69,7 @@ object Objects:
69
69
sealed abstract class Value :
70
70
def show (using Context ): String
71
71
72
+ sealed abstract class ValueElement extends Value
72
73
73
74
/**
74
75
* A reference caches the values for outers and immutable fields.
@@ -77,7 +78,7 @@ object Objects:
77
78
valsMap : mutable.Map [Symbol , Value ],
78
79
varsMap : mutable.Map [Symbol , Heap .Addr ],
79
80
outersMap : mutable.Map [ClassSymbol , Value ])
80
- extends Value :
81
+ extends ValueElement :
81
82
protected val vals : mutable.Map [Symbol , Value ] = valsMap
82
83
protected val vars : mutable.Map [Symbol , Heap .Addr ] = varsMap
83
84
protected val outers : mutable.Map [ClassSymbol , Value ] = outersMap
@@ -170,7 +171,7 @@ object Objects:
170
171
/**
171
172
* Represents a lambda expression
172
173
*/
173
- case class Fun (code : Tree , thisV : Value , klass : ClassSymbol , env : Env .Data ) extends Value :
174
+ case class Fun (code : Tree , thisV : ValueElement , klass : ClassSymbol , env : Env .Data ) extends Value :
174
175
def show (using Context ) = " Fun(" + code.show + " , " + thisV.show + " , " + klass.show + " )"
175
176
176
177
/**
@@ -183,7 +184,7 @@ object Objects:
183
184
def show (using Context ) = refs.map(_.show).mkString(" [" , " ," , " ]" )
184
185
185
186
/** A cold alias which should not be used during initialization. */
186
- case object Cold extends Value :
187
+ case object Cold extends ValueElement :
187
188
def show (using Context ) = " Cold"
188
189
189
190
val Bottom = RefSet (ListSet .empty)
@@ -240,7 +241,7 @@ object Objects:
240
241
obj
241
242
end doCheckObject
242
243
243
- def checkObjectAccess (clazz : ClassSymbol )(using data : Data , ctx : Context , pendingTrace : Trace ): Value =
244
+ def checkObjectAccess (clazz : ClassSymbol )(using data : Data , ctx : Context , pendingTrace : Trace ): ObjectRef =
244
245
val index = data.checkingObjects.indexOf(ObjectRef (clazz))
245
246
246
247
if index != - 1 then
@@ -466,7 +467,7 @@ object Objects:
466
467
val config = Config (thisV, summon[Env .Data ], Heap .getHeapData())
467
468
super .get(config, expr).map(_.value)
468
469
469
- def cachedEval (thisV : Value , expr : Tree , cacheResult : Boolean )(fun : Tree => Value )(using Heap .MutableData , Env .Data ): Value =
470
+ def cachedEval (thisV : ValueElement , expr : Tree , cacheResult : Boolean )(fun : Tree => Value )(using Heap .MutableData , Env .Data ): Value =
470
471
val config = Config (thisV, summon[Env .Data ], Heap .getHeapData())
471
472
val result = super .cachedEval(config, expr, cacheResult, default = Res (Bottom , Heap .getHeapData())) { expr =>
472
473
Res (fun(expr), Heap .getHeapData())
@@ -542,7 +543,7 @@ object Objects:
542
543
refs.map(ref => ref.widen(height)).join
543
544
544
545
case Fun (code, thisV, klass, env) =>
545
- Fun (code, thisV.widen(height), klass, env.widen(height))
546
+ Fun (code, thisV.widen(height). asInstanceOf [ ValueElement ] , klass, env.widen(height))
546
547
547
548
case ref @ OfClass (klass, outer, _, args, env) =>
548
549
val outer2 = outer.widen(height - 1 )
@@ -619,13 +620,14 @@ object Objects:
619
620
else
620
621
Env .resolveEnv(meth.owner.enclosingMethod, ref, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
621
622
623
+ assert(thisV.isInstanceOf [ValueElement ], " thisV = " + thisV)
622
624
val env2 = Env .of(ddef, args.map(_.value), outerEnv)
623
625
extendTrace(ddef) {
624
626
given Env .Data = env2
625
627
// eval(ddef.rhs, ref, cls, cacheResult = true)
626
628
cache.cachedEval(ref, ddef.rhs, cacheResult = true ) { expr =>
627
629
Returns .installHandler(meth)
628
- val res = cases(expr, thisV, cls)
630
+ val res = cases(expr, thisV. asInstanceOf [ ValueElement ] , cls)
629
631
val returns = Returns .popHandler(meth)
630
632
res.join(returns)
631
633
}
@@ -699,8 +701,8 @@ object Objects:
699
701
* @param receiver The type of the receiver.
700
702
* @param needResolve Whether the target of the selection needs resolution?
701
703
*/
702
- def select (thisV : Value , field : Symbol , receiver : Type , needResolve : Boolean = true ): Contextual [Value ] = log(" select " + field.show + " , this = " + thisV .show, printer, (_ : Value ).show) {
703
- thisV match
704
+ def select (value : Value , field : Symbol , receiver : Type , needResolve : Boolean = true ): Contextual [Value ] = log(" select " + field.show + " , this = " + value .show, printer, (_ : Value ).show) {
705
+ value match
704
706
case Cold =>
705
707
report.warning(" Using cold alias" , Trace .position)
706
708
Bottom
@@ -814,11 +816,11 @@ object Objects:
814
816
else
815
817
// Widen the outer to finitize the domain. Arguments already widened in `evalArgs`.
816
818
val (outerWidened, envWidened) =
817
- if klass.owner.isClass then
819
+ if klass.owner.isClass then // For top-level classes, klass.owner is the enclosing package, which is a class
818
820
(outer.widen(1 ), Env .NoEnv )
819
821
else
820
822
// klass.enclosingMethod returns its primary constructor
821
- Env .resolveEnv(klass.owner.enclosingMethod, outer, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
823
+ Env .resolveEnv(klass.owner.enclosingMethod, outer. asInstanceOf [ ValueElement ] , summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
822
824
823
825
val instance = OfClass (klass, outerWidened, ctor, args.map(_.value), envWidened)
824
826
callConstructor(instance, ctor, args)
@@ -848,7 +850,7 @@ object Objects:
848
850
* @param thisV The value for `this` where the variable is used.
849
851
* @param sym The symbol of the variable.
850
852
*/
851
- def readLocal (thisV : Value , sym : Symbol ): Contextual [Value ] = log(" reading local " + sym.show, printer, (_ : Value ).show) {
853
+ def readLocal (thisV : ValueElement , sym : Symbol ): Contextual [Value ] = log(" reading local " + sym.show, printer, (_ : Value ).show) {
852
854
def isByNameParam (sym : Symbol ) = sym.is(Flags .Param ) && sym.info.isInstanceOf [ExprType ]
853
855
Env .resolveEnv(sym.enclosingMethod, thisV, summon[Env .Data ]) match
854
856
case Some (thisV -> env) =>
@@ -902,7 +904,7 @@ object Objects:
902
904
* @param sym The symbol of the variable.
903
905
* @param value The value of the rhs of the assignment.
904
906
*/
905
- def writeLocal (thisV : Value , sym : Symbol , value : Value ): Contextual [Value ] = log(" write local " + sym.show + " with " + value.show, printer, (_ : Value ).show) {
907
+ def writeLocal (thisV : ValueElement , sym : Symbol , value : Value ): Contextual [Value ] = log(" write local " + sym.show + " with " + value.show, printer, (_ : Value ).show) {
906
908
907
909
assert(sym.is(Flags .Mutable ), " Writing to immutable variable " + sym.show)
908
910
Env .resolveEnv(sym.enclosingMethod, thisV, summon[Env .Data ]) match
@@ -960,13 +962,14 @@ object Objects:
960
962
* @param klass The enclosing class where the expression is located.
961
963
* @param cacheResult It is used to reduce the size of the cache.
962
964
*/
963
- def eval (expr : Tree , thisV : Value , klass : ClassSymbol , cacheResult : Boolean = false ): Contextual [Value ] = log(" evaluating " + expr.show + " , this = " + thisV.show + " , regions = " + Regions .show + " in " + klass.show, printer, (_ : Value ).show) {
965
+ def eval (expr : Tree , thisV : ValueElement , klass : ClassSymbol , cacheResult : Boolean = false ): Contextual [Value ] = log(" evaluating " + expr.show + " , this = " + thisV.show + " , regions = " + Regions .show + " in " + klass.show, printer, (_ : Value ).show) {
966
+ // assert(thisV.isInstanceOf[ValueElement], "thisV is not ValueElement, " + "evaluating " + expr.show + ", this = " + thisV.show)
964
967
cache.cachedEval(thisV, expr, cacheResult) { expr => cases(expr, thisV, klass) }
965
968
}
966
969
967
970
968
971
/** Evaluate a list of expressions */
969
- def evalExprs (exprs : List [Tree ], thisV : Value , klass : ClassSymbol ): Contextual [List [Value ]] =
972
+ def evalExprs (exprs : List [Tree ], thisV : ValueElement , klass : ClassSymbol ): Contextual [List [Value ]] =
970
973
exprs.map { expr => eval(expr, thisV, klass) }
971
974
972
975
/** Handles the evaluation of different expressions
@@ -977,7 +980,7 @@ object Objects:
977
980
* @param thisV The value for `C.this` where `C` is represented by the parameter `klass`.
978
981
* @param klass The enclosing class where the expression `expr` is located.
979
982
*/
980
- def cases (expr : Tree , thisV : Value , klass : ClassSymbol ): Contextual [Value ] = log(" evaluating " + expr.show + " , this = " + thisV.show + " in " + klass.show, printer, (_ : Value ).show) {
983
+ def cases (expr : Tree , thisV : ValueElement , klass : ClassSymbol ): Contextual [Value ] = log(" evaluating " + expr.show + " , this = " + thisV.show + " in " + klass.show, printer, (_ : Value ).show) {
981
984
val trace2 = trace.add(expr)
982
985
983
986
expr match
@@ -1179,7 +1182,7 @@ object Objects:
1179
1182
* Object access elission happens when the object access is used as a prefix
1180
1183
* in `new o.C` and `C` does not need an outer.
1181
1184
*/
1182
- def evalType (tp : Type , thisV : Value , klass : ClassSymbol , elideObjectAccess : Boolean = false ): Contextual [Value ] = log(" evaluating " + tp.show, printer, (_ : Value ).show) {
1185
+ def evalType (tp : Type , thisV : ValueElement , klass : ClassSymbol , elideObjectAccess : Boolean = false ): Contextual [Value ] = log(" evaluating " + tp.show, printer, (_ : Value ).show) {
1183
1186
tp match
1184
1187
case _ : ConstantType =>
1185
1188
Bottom
@@ -1229,7 +1232,7 @@ object Objects:
1229
1232
}
1230
1233
1231
1234
/** Evaluate arguments of methods and constructors */
1232
- def evalArgs (args : List [Arg ], thisV : Value , klass : ClassSymbol ): Contextual [List [ArgInfo ]] =
1235
+ def evalArgs (args : List [Arg ], thisV : ValueElement , klass : ClassSymbol ): Contextual [List [ArgInfo ]] =
1233
1236
val argInfos = new mutable.ArrayBuffer [ArgInfo ]
1234
1237
args.foreach { arg =>
1235
1238
val res =
@@ -1429,7 +1432,7 @@ object Objects:
1429
1432
* @param thisV The value for `C.this` where `C` is represented by the parameter `klass`.
1430
1433
* @param klass The enclosing class where the type `tref` is located.
1431
1434
*/
1432
- def outerValue (tref : TypeRef , thisV : Value , klass : ClassSymbol ): Contextual [Value ] =
1435
+ def outerValue (tref : TypeRef , thisV : ValueElement , klass : ClassSymbol ): Contextual [Value ] =
1433
1436
val cls = tref.classSymbol.asClass
1434
1437
if tref.prefix == NoPrefix then
1435
1438
val enclosing = cls.owner.lexicallyEnclosingClass.asClass
0 commit comments