Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static all the things #22

Closed
wants to merge 85 commits into from
Closed

Static all the things #22

wants to merge 85 commits into from

Conversation

retronym
Copy link
Owner

No description provided.

som-snytt and others added 5 commits March 15, 2016 12:41
Allow an infix extractor named `|`, when backquoted.
This overrides default implementation from PartialFunction which used
both contains(x) and get(x) with getOrElse.
@retronym retronym changed the title Topic/trait statics Static all the things May 11, 2016
@retronym retronym force-pushed the topic/trait-statics branch 2 times, most recently from 9e4587a to 401c29e Compare May 17, 2016 05:58
Make broken JAR files on compiler classpath cause a fatal error
@retronym retronym force-pushed the topic/trait-statics branch 4 times, most recently from c50b219 to 0daf45d Compare May 19, 2016 12:18
Steve Robinson and others added 14 commits May 19, 2016 10:54
For Range and NumericRange, toString will indicate the step
if it is not 1.

Additionally, indicate empty ranges and ranges which are not
"exact".

For a "mapped" range, used by `Range.Double`, toString
includes the underlying range and the simple type of the step
(to distinguish Double from BigDecimal).
Refactor the ScriptEngine support to an adaptor atop the
IMain API.

Allow references to resolve to context attributes. (The
attributes must be defined at compilation time, though
they may resolve to updated values at evaluation time.)

This means that attributes are not bound statically in
REPL history. In particular, we forgo the trick of binding
attributes named "name: Type" as typed values.

Instead, an `x` bound in dynamic context is injected into
the script as a dynamic selection `$ctx.x` where `ctx`
performs the look-up in the script context.

When a compiled script is re-evaluated, a new instance of
the script class is created and defined symbols are
rebound.

The context stdout writer is handled with `Console.withOut`,
with bytes decoded using the default charset.

Compilation errors are thrown as ScriptException with the
first reported error.

This commit doesn't attempt dynamic selection from objects
in context. Currently, script must cast.
`convertToAssignment` is triggered on a type error but it doesn't seem
to really care what the error is as long as the expression can be
converted to an assignment expression.

This patch fixes that by checking whether the qualifier of the selection
contains any errors before deciding to continue with the conversion.
* Enhanced Scaladocs with groupings and clarifications
* traverse now runs the last step like sequence
* A few minor non-semantic changes to method implementations
[Build] Include missing web assets in scaladoc
@retronym retronym force-pushed the topic/trait-statics branch 3 times, most recently from 6d2a838 to 7eefe33 Compare May 30, 2016 03:42
lrytz and others added 5 commits May 30, 2016 08:52
Renaming -Yopt to -opt revealed that we're passing the flag when
building the locker (and optionally the starr) version. This is not
necessary: when building the next stage with the flag enabled, the same
optimizations are performed no matter if the current stage was built
with the flag or not.
Don't pass -opt to starr / locker build in the bootstrap script
SI-9794 Error advice uses decoded method name
SI-9382 Privatize enhanced x in Tuple2Zipped.Ops
Improvements to deprecations related to `since` parameter
@retronym retronym force-pushed the topic/trait-statics branch from 7eefe33 to 82d83a1 Compare May 31, 2016 03:20
The underlying transformer has a by-name parameter for the
to provide the `to` tree, but this was strict in the layers
of API above.

Tree sharing is frowned upon in general as it leads to cross
talk when, e.g., the erasure typechecker mutates the
`tpe` field of the shared tree in different context.
@retronym retronym force-pushed the topic/trait-statics branch from 82d83a1 to a9d5a6d Compare May 31, 2016 05:53
retronym and others added 11 commits June 1, 2016 11:15
The body of lambdas is compiled into a synthetic method
in the enclosing class. Previously, this method was a public
virtual method named `fully$qualified$Class$$anonfun$n`.
For lambdas that didn't capture a `this` reference, a static
method was used.

This commit changes two aspects.

Firstly, all lambda impl methods are now emitted static.
An extra parameter is added to those that require a this
reference.

This is an improvement as it:

  - allows, shorter, more readable names for the lambda impl method
  - avoids pollution of the vtable of the class. Note that javac uses
    private instance methods, rather than public static methods. If
    we followed its lead, we would be unable to support important use
    cases in our inliner

Secondly, the name of the enclosing method has been included in
the name of the lambda impl method to improve debuggability and
to improve serialization compatibility. The serialization improvement
comes from the way that fresh names for the impl methods are
allocated: adding or removing lambdas in methods not named "foo" won't
change the numbering of the `anonfun$foo$n` impl methods from methods
named "foo". This is in line with user expectations about anonymous
class and lambda serialization stability. Brian Goetz has described
this tricky area well in:

  http://cr.openjdk.java.net/~briangoetz/eg-attachments/lambda-serialization.html

This commit doesn't go as far a Javac, we don't use the hash of the
lambda type info, param names, etc to map to a lambda impl method name.
As such, we are more prone to the type-1 and -2 failures described there.
However, our Scala 2.11.8 has similar characteristics, so we aren't going
backwards.

Special case in the naming: Use "new" rather than "<init>" for constructor enclosed
lambdas, as javac does.

I have also changed the way that "delambdafy target" methods are identifed.
Rather than relying on the naming convention, I have switched to using a
symbol attachment. The assumption is that we only need to identify them
from within the same compilation unit.

This means we can distinguish impl metbods for expanded functions
(ones called from an `apply` method of an ahead-of-time expanded
anonfun class), from those that truly end up as targets for lambda
metafactory. Only the latter are translated to static methods in
this patch.
This corrects an error in the change to the trait encoding
in scala#5003: getters in traits should have empty bodies and
be emitted as abstract.

```
% ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T
Compiled from "test.scala"
public interface T {
  public abstract void T$_setter_$x_$eq(int);

  public int x();
    Code:
       0: aload_0
       1: invokeinterface #15,  1           // InterfaceMethod x:()I
       6: ireturn

  public int y();
    Code:
       0: aload_0
       1: invokeinterface #20,  1           // InterfaceMethod y:()I
       6: ireturn

  public void y_$eq(int);
    Code:
       0: aload_0
       1: iload_1
       2: invokeinterface #24,  2           // InterfaceMethod y_$eq:(I)V
       7: return

  public void $init$();
    Code:
       0: aload_0
       1: bipush        42
       3: invokeinterface #29,  2           // InterfaceMethod T$_setter_$x_$eq:(I)V
       8: aload_0
       9: bipush        24
      11: invokeinterface #24,  2           // InterfaceMethod y_$eq:(I)V
      16: return
}

% qscalac sandbox/test.scala && javap -c T
Compiled from "test.scala"
public interface T {
  public abstract void T$_setter_$x_$eq(int);

  public abstract int x();

  public abstract int y();

  public abstract void y_$eq(int);

  public static void $init$(T);
    Code:
       0: aload_0
       1: bipush        42
       3: invokeinterface #21,  2           // InterfaceMethod T$_setter_$x_$eq:(I)V
       8: aload_0
       9: bipush        24
      11: invokeinterface #23,  2           // InterfaceMethod y_$eq:(I)V
      16: return

  public void $init$();
    Code:
       0: aload_0
       1: invokestatic  #27                 // Method $init$:(LT;)V
       4: return
}
```
This partially reverts the fix for SI-5278 made in 7a99c03.
The original motivation for this case to avoid bytecode that
stretched platform limitations in Android.

For super calls to Scala defined trait methods, we won't
use `invokespecial`, but rather use `invokestatic` to a
static trait implementation method. As such, we can continue
to prune redundant Scala interfaces.

It might be worth considering removing the pruning of
redundant parents altoghether, though:

  - We no longer include `ScalaObject` as a parent of every class,
    which was mentioned as a problem in SI-5728.
  - Scala 2.12 has left Android behind for the time being
    due to use of Java 8 facilities.
  - javac doesn't do this, so why should we?
this change is a bit scary because it changes code that's not been
changed in 11 years
scala@7fa7c93#diff-d5789e5ae5061197d782d08324b260dbL214
And use this as the target of the default methods or
statically resolved super or $init calls.

The call-site change is predicated on `-Yuse-trait-statics`
as a stepping stone for experimentation / bootstrapping.

I have performed this transformation in the backend,
rather than trying to reflect this in the view from
Scala symbols + ASTs.

```
> ;scalac sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:13 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial #14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokespecial #17                 // Method T.$init$:()V
[info]        8: getstatic     #23                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           #24                 // String C
[info]       13: invokevirtual #28                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokespecial #32                 // Method T.foo:()I
[info]       20: pop
[info]       21: return
[info] }
> ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:39 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial #14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokestatic  #18                 // Method T.$init$:(LT;)V
[info]        8: getstatic     #24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           #25                 // String C
[info]       13: invokevirtual #29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokestatic  #33                 // Method T.foo:(LT;)I
[info]       20: pop
[info]       21: return
[info] }
> eval "javap -classpath . -c -private T".!!
[info] ans: String = Compiled from "test.scala"
[info] public interface T {
[info]   public static int foo(T);
[info]     Code:
[info]        0: iconst_0
[info]        1: ireturn
[info]
[info]   public int foo();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  #15                 // Method foo:(LT;)I
[info]        4: ireturn
[info]
[info]   public static void $init$(T);
[info]     Code:
[info]        0: getstatic     #24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]        3: ldc           #25                 // String T
[info]        5: invokevirtual #29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]        8: return
[info]
[info] }
```
@retronym retronym force-pushed the topic/trait-statics branch from a9d5a6d to 3787426 Compare June 1, 2016 01:19
@retronym retronym closed this Jun 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.