@@ -206,22 +206,25 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
206
206
/** Create non-threadsafe lazy accessor equivalent to such code
207
207
* ```
208
208
* def methodSymbol() = {
209
- * if (flag) target
210
- * else {
209
+ * if (!flag) {
211
210
* target = rhs
212
211
* flag = true
213
212
* nullable = null
214
- * target
215
- * }
216
213
* }
214
+ * target
217
215
* }
218
216
* ```
219
217
*/
220
- def mkNonThreadSafeDef (target : Tree , flag : Tree , rhs : Tree , nullables : List [Symbol ])(implicit ctx : Context ): If = {
221
- val stats = new mutable.ListBuffer [Tree ]
222
- if (! isWildcardArg(rhs)) stats += target.becomes(rhs)
223
- stats += flag.becomes(Literal (Constant (true ))) ++= nullOut(nullables)
224
- If (flag.ensureApplied, target.ensureApplied, Block (stats.toList, target.ensureApplied))
218
+ def mkNonThreadSafeDef (sym : Symbol , flag : Symbol , target : Symbol , rhs : Tree )(implicit ctx : Context ): DefDef = {
219
+ val targetRef = ref(target)
220
+ val flagRef = ref(flag)
221
+ val stats = targetRef.becomes(rhs) :: flagRef.becomes(Literal (Constant (true ))) :: nullOut(nullableFor(sym))
222
+ val init = If (
223
+ flagRef.ensureApplied.select(nme.UNARY_! ).ensureApplied,
224
+ Block (stats.init, stats.last),
225
+ unitLiteral
226
+ )
227
+ DefDef (sym.asTerm, Block (List (init), targetRef.ensureApplied))
225
228
}
226
229
227
230
/** Create non-threadsafe lazy accessor for not-nullable types equivalent to such code
@@ -230,18 +233,20 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
230
233
* if (target eq null) {
231
234
* target = rhs
232
235
* nullable = null
233
- * target
234
- * } else target
236
+ * }
237
+ * target
235
238
* }
236
239
* ```
237
240
*/
238
- def mkDefNonThreadSafeNonNullable (target : Symbol , rhs : Tree , nullables : List [Symbol ])(implicit ctx : Context ): If = {
239
- val cond = ref(target).select(nme.eq).appliedTo(Literal (Constant (null )))
240
- val exp = ref(target)
241
- val setTarget = exp.becomes(rhs)
242
- val setNullables = nullOut(nullables)
243
- val init = Block (setTarget :: setNullables, exp)
244
- If (cond, init, exp)
241
+ def mkDefNonThreadSafeNonNullable (sym : Symbol , target : Symbol , rhs : Tree )(implicit ctx : Context ): DefDef = {
242
+ val targetRef = ref(target)
243
+ val stats = targetRef.becomes(rhs) :: nullOut(nullableFor(sym))
244
+ val init = If (
245
+ targetRef.select(nme.eq).appliedTo(Literal (Constant (null ))),
246
+ Block (stats.init, stats.last),
247
+ unitLiteral
248
+ )
249
+ DefDef (sym.asTerm, Block (List (init), targetRef.ensureApplied))
245
250
}
246
251
247
252
def transformMemberDefNonVolatile (x : ValOrDefDef )(implicit ctx : Context ): Thicket = {
@@ -255,16 +260,15 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
255
260
).enteredAfter(this )
256
261
257
262
val containerTree = ValDef (containerSymbol, defaultValue(tpe))
258
- if (x.tpe.isNotNull && tpe <:< defn.ObjectType ) { // can use 'null' value instead of flag
259
- val slowPath = DefDef (x.symbol.asTerm, mkDefNonThreadSafeNonNullable(containerSymbol, x.rhs, nullableFor(x.symbol)))
260
- Thicket (containerTree, slowPath )
263
+ if (x.tpe.isNotNull && tpe <:< defn.ObjectType ) {
264
+ // can use 'null' value instead of flag
265
+ Thicket (containerTree, mkDefNonThreadSafeNonNullable(x.symbol, containerSymbol, x.rhs) )
261
266
}
262
267
else {
263
268
val flagName = LazyBitMapName .fresh(x.name.asTermName)
264
269
val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags | Flags .Private , defn.BooleanType ).enteredAfter(this )
265
270
val flag = ValDef (flagSymbol, Literal (Constant (false )))
266
- val slowPath = DefDef (x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), x.rhs, nullableFor(x.symbol)))
267
- Thicket (containerTree, flag, slowPath)
271
+ Thicket (containerTree, flag, mkNonThreadSafeDef(x.symbol, flagSymbol, containerSymbol, x.rhs))
268
272
}
269
273
}
270
274
0 commit comments