Skip to content

Commit 33a5836

Browse files
committed
Try special casing the resolveEnv function for locals
1 parent c6d5d2b commit 33a5836

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

compiler/src/dotty/tools/dotc/transform/init/Objects.scala

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ class Objects(using Context @constructorOnly):
410410
new LocalEnv(argMap, meth, outer)(valsMap = mutable.Map.empty, varsMap = mutable.Map.empty)
411411

412412
def ofDefDef(ddef: DefDef, args: List[Value], outer: Data)(using Context): Data =
413+
// println(ddef.show)
413414
val params = ddef.termParamss.flatten.map(_.symbol)
414415
assert(args.size == params.size, "arguments = " + args.size + ", params = " + params.size)
415416
assert(ddef.symbol.owner.isClass ^ (outer != NoEnv), "ddef.owner = " + ddef.symbol.owner.show + ", outer = " + outer + ", " + ddef.source)
@@ -452,17 +453,43 @@ class Objects(using Context @constructorOnly):
452453
*
453454
* @return the environment and value for `this` owned by the given method.
454455
*/
455-
def resolveEnv(meth: Symbol, thisV: ThisValue, env: Data)(using Context): Option[(ThisValue, Data)] = log("Resolving env for " + meth.show + ", this = " + thisV.show + ", env = " + env.show, printer) {
456+
def _resolveEnvByValue(target: Symbol, thisV: ThisValue, env: Data)(using Context): Option[(ThisValue, Data)] = log("Resolving env for " + target.show + ", this = " + thisV.show + ", env = " + env.show, printer) {
457+
env match
458+
case localEnv: LocalEnv =>
459+
if localEnv.getVal(target).isDefined then Some(thisV -> localEnv)
460+
else if localEnv.getVar(target).isDefined then Some(thisV -> localEnv)
461+
else _resolveEnvByValue(target, thisV, localEnv.outer)
462+
case NoEnv =>
463+
thisV match
464+
case ref: OfClass =>
465+
ref.outer match
466+
case outer : ThisValue =>
467+
_resolveEnvByValue(target, outer, ref.env)
468+
case _ =>
469+
// TODO: properly handle the case where ref.outer is ValueSet
470+
None
471+
case _ =>
472+
None
473+
}
474+
475+
def resolveEnvByValue(target: Symbol, thisV: ThisValue, env: Data)(using Context): Option[(ThisValue, Data)] =
476+
// println("the target: " + target.show + "its owner: " + target.owner.show + " the env: " + env.show)
477+
val e = _resolveEnvByValue(target, thisV, env)
478+
if e.isDefined then println(e.get._2.show)
479+
else println("NONE")
480+
e
481+
482+
def resolveEnvByOwner(meth: Symbol, thisV: ThisValue, env: Data)(using Context): Option[(ThisValue, Data)] = log("Resolving env for " + meth.show + ", this = " + thisV.show + ", env = " + env.show, printer) {
456483
env match
457484
case localEnv: LocalEnv =>
458485
if localEnv.meth == meth then Some(thisV -> env)
459-
else resolveEnv(meth, thisV, localEnv.outer)
486+
else resolveEnvByOwner(meth, thisV, localEnv.outer)
460487
case NoEnv =>
461488
thisV match
462489
case ref: OfClass =>
463490
ref.outer match
464491
case outer : ThisValue =>
465-
resolveEnv(meth, outer, ref.env)
492+
resolveEnvByOwner(meth, outer, ref.env)
466493
case _ =>
467494
// TODO: properly handle the case where ref.outer is ValueSet
468495
None
@@ -725,7 +752,8 @@ class Objects(using Context @constructorOnly):
725752
if meth.owner.isClass then
726753
(ref, Env.NoEnv)
727754
else
728-
Env.resolveEnv(meth.owner.enclosingMethod, ref, summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
755+
// println("1: " + meth.show + " env : " + summon[Env.Data].show)
756+
Env.resolveEnvByOwner(meth.owner.enclosingMethod, ref, summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
729757

730758
val env2 = Env.ofDefDef(ddef, args.map(_.value), outerEnv)
731759
extendTrace(ddef) {
@@ -963,7 +991,8 @@ class Objects(using Context @constructorOnly):
963991
(thisV.widenRefOrCold(1), Env.NoEnv)
964992
else
965993
// klass.enclosingMethod returns its primary constructor
966-
Env.resolveEnv(klass.owner.enclosingMethod, thisV, summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
994+
// println("callsite 2: " + klass.show + " env : " + summon[Env.Data].show)
995+
Env.resolveEnvByOwner(klass.owner.enclosingMethod, thisV, summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
967996

968997
val instance = OfClass(klass, outerWidened, ctor, args.map(_.value), envWidened)
969998
callConstructor(instance, ctor, args)
@@ -983,7 +1012,6 @@ class Objects(using Context @constructorOnly):
9831012
Env.setLocalVar(sym, addr)
9841013
Heap.writeJoin(addr, value)
9851014
else
986-
System.out.println("initLocal sym: " + sym.show + " val: " + value.show + " data: " + data.show)
9871015
Env.setLocalVal(sym, value)
9881016
}
9891017

@@ -994,7 +1022,8 @@ class Objects(using Context @constructorOnly):
9941022
*/
9951023
def readLocal(thisV: ThisValue, sym: Symbol): Contextual[Value] = log("reading local " + sym.show, printer, (_: Value).show) {
9961024
def isByNameParam(sym: Symbol) = sym.is(Flags.Param) && sym.info.isInstanceOf[ExprType]
997-
Env.resolveEnv(sym.enclosingMethod, thisV, summon[Env.Data]) match
1025+
// println("callsite 3: " + sym.show + " env : " + summon[Env.Data].show)
1026+
Env.resolveEnvByValue(sym, thisV, summon[Env.Data]) match
9981027
case Some(thisV -> env) =>
9991028
if sym.is(Flags.Mutable) then
10001029
// Assume forward reference check is doing a good job
@@ -1017,15 +1046,12 @@ class Objects(using Context @constructorOnly):
10171046
val rhs = sym.defTree.asInstanceOf[ValDef].rhs
10181047
eval(rhs, thisV, sym.enclosingClass.asClass, cacheResult = true)
10191048
else
1020-
System.out.println("env: " + env.show)
1021-
System.out.println("sym: " + sym.show)
10221049
// Assume forward reference check is doing a good job
10231050
val value = Env.valValue(sym)
10241051
if isByNameParam(sym) then
10251052
value match
10261053
case fun: Fun =>
10271054
given Env.Data = Env.ofByName(sym, fun.env)
1028-
System.out.println("created new env " + fun.code.show)
10291055
eval(fun.code, fun.thisV, fun.klass)
10301056
case Cold =>
10311057
report.warning("Calling cold by-name alias. " + Trace.show, Trace.position)
@@ -1052,8 +1078,8 @@ class Objects(using Context @constructorOnly):
10521078
*/
10531079
def writeLocal(thisV: ThisValue, sym: Symbol, value: Value): Contextual[Value] = log("write local " + sym.show + " with " + value.show, printer, (_: Value).show) {
10541080
assert(sym.is(Flags.Mutable), "Writing to immutable variable " + sym.show)
1055-
1056-
Env.resolveEnv(sym.enclosingMethod, thisV, summon[Env.Data]) match
1081+
// println("callsite 4: " + sym.show + " env : " + summon[Env.Data].show)
1082+
Env.resolveEnvByValue(sym, thisV, summon[Env.Data]) match
10571083
case Some(thisV -> env) =>
10581084
given Env.Data = env
10591085
Env.getVar(sym) match
@@ -1189,6 +1215,7 @@ class Objects(using Context @constructorOnly):
11891215
withTrace(trace2) { call(receiver, ref.symbol, args, receiver = qual.tpe, superType = NoType) }
11901216

11911217
case id: Ident =>
1218+
// println("ID : " + id.show)
11921219
id.tpe match
11931220
case TermRef(NoPrefix, _) =>
11941221
// resolve this for the local method
@@ -1258,6 +1285,7 @@ class Objects(using Context @constructorOnly):
12581285
Fun(ddef, thisV, klass, summon[Env.Data])
12591286

12601287
case Block(stats, expr) =>
1288+
// println("BLOCK DATA : " + expr.show)
12611289
evalExprs(stats, thisV, klass)
12621290
eval(expr, thisV, klass)
12631291

0 commit comments

Comments
 (0)