[indylambda] Relieve LambdaMetafactory of boxing duties [ci: last-only]#4497
[indylambda] Relieve LambdaMetafactory of boxing duties [ci: last-only]#4497retronym merged 2 commits intoscala:2.11.xfrom
Conversation
|
typos in the commit message: " |
|
Could you remove the |
|
|
There was a problem hiding this comment.
I couldn't easily/lazily convince myself this deals correctly with nested templates. Could you shed some light on that?
There was a problem hiding this comment.
The train has already been through Flatten Plains, almost at the terminal station.
qscala -Xshow-phases 2>&1| tail -10
lambdalift 17 move nested functions to top level
constructors 18 move field definitions into constructors
flatten 19 eliminate inner classes
mixin 20 mixin composition
cleanup 21 platform-specific cleanups, generate reflective calls
🚅delambdafy 22 remove lambdas
icode 23 generate portable intermediate code
jvm 24 generate JVM bytecode
terminal 25 the last phase during a compilation run
There was a problem hiding this comment.
Ah yes. I don't spend nearly enough time in back country.
`LambdaMetafactory` generates code to perform a limited number
of type adaptations when delegating from its implementation of
the functional interface method to the lambda target method.
These adaptations are: numeric widening, casting, boxing and unboxing.
However, the semantics of unboxing numerics in Java differs to Scala:
they treat `UNBOX(null)` as cause to raise a `NullPointerException`,
Scala (in `BoxesRuntime.unboxTo{Byte,Short,...}`) reinterprets the
null as zero.
Furthermore, Java has no idea how to adapt between a value class and
its wrapped type, nor from a void return to `BoxedUnit`.
This commit detects when the lambda target method would require
such adaptation. If it does, an extra method, `$anonfun$1$adapted` is
created to perform the adaptation, and this is used as the target
of the lambda.
This obviates the use of `JProcedureN` for `Unit` returning
lambdas, we know use `JFunctionN` as the functional interface
and bind this to an `$adapted` method that summons the instance
of `BoxedUnit` after calling the `void` returning lambda target.
The enclosed test cases fail without boxing changes. They don't
execute with indylambda enabled under regular partest runs yet,
you need to add scala-java8-compat to scala-library and pass
the SCALAC_OPTS to partest manually to try this out, as described
in scala#4463. Once we enable indylambda
by default, however, this test will exercise the code in this patch
all the time.
It is also possible to run the tests with:
```
% curl https://oss.sonatype.org/content/repositories/releases/org/scala-lang/modules/scala-java8-compat_2.11/0.4.0/scala-java8-compat_2.11-0.4.0.jar > scala-java8-compat_2.11-0.4.0.jar
% export INDYLAMBDA="-Ydelambdafy:method -Ybackend:GenBCode -target:jvm-1.8 -classpath .:scala-java8-compat_2.11-0.4.0.jar"
qscalac $INDYLAMBDA test/files/run/indylambda-boxing/*.scala && qscala $INDYLAMBDA Test
```
|
@lrytz fxed the typo in the commit message |
14929d7 to
6ad9b44
Compare
There was a problem hiding this comment.
I'll revert this in the followup PR.
|
LGTM! |
[indylambda] Relieve LambdaMetafactory of boxing duties [ci: last-only]
LambdaMetafactorygenerates code to perform a limited number of typeadaptations when delegating from its implementation of the functional
interface method to the lambda target method.
These adaptations are: numeric widening, casting, boxing and unboxing.
However, the semantics of unboxing numerics in Java differs to Scala: they
treat
UNBOX(null)as cause to rause aNullPointerException, Scala (inBoxesRuntime.unboxTo{Byte,Short,...}) reinterprets the null as zero.Furthermore, Java has no idea how to adapt between a value class and its
wrapped type, nor from a void return to
BoxedUnit.This commit detects when the lambda target method would require such
adaptation. If it does, an extra method,
$anonfun$1$adaptedis created toperform the adaptation, and this is used as the target of the lambda.
This obviates the use of
JProcedureNforUnitreturning lambdas, weknow use
JFunctionNas the functional interface and bind this to an$adaptedmethod that summons the instance ofBoxedUnitafter callingthe
voidreturning lambda target.The enclosed test cases fail without boxing changes. They don't execute
with indylambda enabled under regular partest runs yet, you need to add
scala-java8-compat to scala-library and pass the SCALAC_OPTS to partest
manually to try this out, as described in
#4463. Once we enable indylambda by
default, however, this test will exercise the code in this patch all the
time.
It is also possible to run the tests with: