@@ -6,6 +6,8 @@ import ast.Trees._, ast.tpd, core._
6
6
import Contexts .Context , Types ._ , Decorators ._ , Symbols ._ , DenotTransformers ._
7
7
import SymDenotations ._ , Scopes ._ , StdNames ._ , NameOps ._ , Names ._
8
8
9
+ import scala .reflect .internal .util .Collections
10
+
9
11
/** This phase synthesizes specialized methods for FunctionN, this is done
10
12
* since there are no scala signatures in the bytecode for the specialized
11
13
* methods.
@@ -19,122 +21,163 @@ class SpecializedApplyMethods extends MiniPhaseTransform with InfoTransformer {
19
21
20
22
val phaseName = " specializedApplyMethods"
21
23
24
+ private [this ] var func0Applys : List [Symbol ] = _
25
+ private [this ] var func1Applys : List [Symbol ] = _
26
+ private [this ] var func2Applys : List [Symbol ] = _
27
+ private [this ] var func0 : Symbol = _
28
+ private [this ] var func1 : Symbol = _
29
+ private [this ] var func2 : Symbol = _
30
+
31
+ private def init ()(implicit ctx : Context ): Unit = if (func0Applys eq null ) {
32
+ def specApply (sym : Symbol , ret : Type , args : List [Type ])(implicit ctx : Context ) = {
33
+ val all = args :+ ret
34
+ val name = nme.apply.specializedFor(all, all.map(_.typeSymbol.name), Nil , Nil )
35
+ ctx.newSymbol(sym, name, Flags .Method , MethodType (args, ret))
36
+ }
37
+
38
+ func0 = defn.FunctionClass (0 )
39
+ func0Applys = List (
40
+ specApply(func0, defn.UnitType , Nil ),
41
+ specApply(func0, defn.ByteType , Nil ),
42
+ specApply(func0, defn.ShortType , Nil ),
43
+ specApply(func0, defn.IntType , Nil ),
44
+ specApply(func0, defn.LongType , Nil ),
45
+ specApply(func0, defn.CharType , Nil ),
46
+ specApply(func0, defn.FloatType , Nil ),
47
+ specApply(func0, defn.DoubleType , Nil ),
48
+ specApply(func0, defn.BooleanType , Nil )
49
+ )
50
+ func1 = defn.FunctionClass (1 )
51
+ func1Applys = List (
52
+ specApply(func1, defn.UnitType , List (defn.IntType )),
53
+ specApply(func1, defn.IntType , List (defn.IntType )),
54
+ specApply(func1, defn.FloatType , List (defn.IntType )),
55
+ specApply(func1, defn.LongType , List (defn.IntType )),
56
+ specApply(func1, defn.DoubleType , List (defn.IntType )),
57
+ specApply(func1, defn.UnitType , List (defn.LongType )),
58
+ specApply(func1, defn.BooleanType , List (defn.LongType )),
59
+ specApply(func1, defn.IntType , List (defn.LongType )),
60
+ specApply(func1, defn.FloatType , List (defn.LongType )),
61
+ specApply(func1, defn.LongType , List (defn.LongType )),
62
+ specApply(func1, defn.DoubleType , List (defn.LongType )),
63
+ specApply(func1, defn.UnitType , List (defn.FloatType )),
64
+ specApply(func1, defn.BooleanType , List (defn.FloatType )),
65
+ specApply(func1, defn.IntType , List (defn.FloatType )),
66
+ specApply(func1, defn.FloatType , List (defn.FloatType )),
67
+ specApply(func1, defn.LongType , List (defn.FloatType )),
68
+ specApply(func1, defn.DoubleType , List (defn.FloatType )),
69
+ specApply(func1, defn.UnitType , List (defn.DoubleType )),
70
+ specApply(func1, defn.BooleanType , List (defn.DoubleType )),
71
+ specApply(func1, defn.IntType , List (defn.DoubleType )),
72
+ specApply(func1, defn.FloatType , List (defn.DoubleType )),
73
+ specApply(func1, defn.LongType , List (defn.DoubleType )),
74
+ specApply(func1, defn.DoubleType , List (defn.DoubleType ))
75
+ )
76
+ func2 = defn.FunctionClass (2 )
77
+ func2Applys = List (
78
+ specApply(func2, defn.UnitType , List (defn.IntType , defn.IntType )),
79
+ specApply(func2, defn.BooleanType , List (defn.IntType , defn.IntType )),
80
+ specApply(func2, defn.IntType , List (defn.IntType , defn.IntType )),
81
+ specApply(func2, defn.FloatType , List (defn.IntType , defn.IntType )),
82
+ specApply(func2, defn.LongType , List (defn.IntType , defn.IntType )),
83
+ specApply(func2, defn.DoubleType , List (defn.IntType , defn.IntType )),
84
+ specApply(func2, defn.UnitType , List (defn.IntType , defn.LongType )),
85
+ specApply(func2, defn.BooleanType , List (defn.IntType , defn.LongType )),
86
+ specApply(func2, defn.IntType , List (defn.IntType , defn.LongType )),
87
+ specApply(func2, defn.FloatType , List (defn.IntType , defn.LongType )),
88
+ specApply(func2, defn.LongType , List (defn.IntType , defn.LongType )),
89
+ specApply(func2, defn.DoubleType , List (defn.IntType , defn.LongType )),
90
+ specApply(func2, defn.UnitType , List (defn.IntType , defn.DoubleType )),
91
+ specApply(func2, defn.BooleanType , List (defn.IntType , defn.DoubleType )),
92
+ specApply(func2, defn.IntType , List (defn.IntType , defn.DoubleType )),
93
+ specApply(func2, defn.FloatType , List (defn.IntType , defn.DoubleType )),
94
+ specApply(func2, defn.LongType , List (defn.IntType , defn.DoubleType )),
95
+ specApply(func2, defn.DoubleType , List (defn.IntType , defn.DoubleType )),
96
+ specApply(func2, defn.UnitType , List (defn.LongType , defn.IntType )),
97
+ specApply(func2, defn.BooleanType , List (defn.LongType , defn.IntType )),
98
+ specApply(func2, defn.IntType , List (defn.LongType , defn.IntType )),
99
+ specApply(func2, defn.FloatType , List (defn.LongType , defn.IntType )),
100
+ specApply(func2, defn.LongType , List (defn.LongType , defn.IntType )),
101
+ specApply(func2, defn.DoubleType , List (defn.LongType , defn.IntType )),
102
+ specApply(func2, defn.UnitType , List (defn.LongType , defn.LongType )),
103
+ specApply(func2, defn.BooleanType , List (defn.LongType , defn.LongType )),
104
+ specApply(func2, defn.IntType , List (defn.LongType , defn.LongType )),
105
+ specApply(func2, defn.FloatType , List (defn.LongType , defn.LongType )),
106
+ specApply(func2, defn.LongType , List (defn.LongType , defn.LongType )),
107
+ specApply(func2, defn.DoubleType , List (defn.LongType , defn.LongType )),
108
+ specApply(func2, defn.UnitType , List (defn.LongType , defn.DoubleType )),
109
+ specApply(func2, defn.BooleanType , List (defn.LongType , defn.DoubleType )),
110
+ specApply(func2, defn.IntType , List (defn.LongType , defn.DoubleType )),
111
+ specApply(func2, defn.FloatType , List (defn.LongType , defn.DoubleType )),
112
+ specApply(func2, defn.LongType , List (defn.LongType , defn.DoubleType )),
113
+ specApply(func2, defn.DoubleType , List (defn.LongType , defn.DoubleType )),
114
+ specApply(func2, defn.UnitType , List (defn.DoubleType , defn.IntType )),
115
+ specApply(func2, defn.BooleanType , List (defn.DoubleType , defn.IntType )),
116
+ specApply(func2, defn.IntType , List (defn.DoubleType , defn.IntType )),
117
+ specApply(func2, defn.FloatType , List (defn.DoubleType , defn.IntType )),
118
+ specApply(func2, defn.LongType , List (defn.DoubleType , defn.IntType )),
119
+ specApply(func2, defn.DoubleType , List (defn.DoubleType , defn.IntType )),
120
+ specApply(func2, defn.UnitType , List (defn.DoubleType , defn.LongType )),
121
+ specApply(func2, defn.BooleanType , List (defn.DoubleType , defn.LongType )),
122
+ specApply(func2, defn.IntType , List (defn.DoubleType , defn.LongType )),
123
+ specApply(func2, defn.FloatType , List (defn.DoubleType , defn.LongType )),
124
+ specApply(func2, defn.LongType , List (defn.DoubleType , defn.LongType )),
125
+ specApply(func2, defn.DoubleType , List (defn.DoubleType , defn.LongType )),
126
+ specApply(func2, defn.UnitType , List (defn.DoubleType , defn.DoubleType )),
127
+ specApply(func2, defn.BooleanType , List (defn.DoubleType , defn.DoubleType )),
128
+ specApply(func2, defn.IntType , List (defn.DoubleType , defn.DoubleType )),
129
+ specApply(func2, defn.FloatType , List (defn.DoubleType , defn.DoubleType )),
130
+ specApply(func2, defn.LongType , List (defn.DoubleType , defn.DoubleType )),
131
+ specApply(func2, defn.DoubleType , List (defn.DoubleType , defn.DoubleType ))
132
+ )
133
+ }
134
+
135
+ /** Add symbols for specialized methods to FunctionN */
22
136
def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ) = tp match {
23
137
case tp : ClassInfo if defn.isFunctionClass(sym) => {
24
- def specApply (ret : Type , args : List [Type ])(implicit ctx : Context ) = {
25
- val all = args :+ ret
26
- val name = nme.apply.specializedFor(all, all.map(_.typeSymbol.name), Nil , Nil )
27
- ctx.newSymbol(sym, name, Flags .Method , MethodType (args, ret))
138
+ init()
139
+ val newDecls = sym.name.functionArity match {
140
+ case 0 => func0Applys.foldLeft(tp.decls.cloneScope) {
141
+ (decls, sym) => decls.enter(sym); decls
142
+ }
143
+ case 1 => func1Applys.foldLeft(tp.decls.cloneScope) {
144
+ (decls, sym) => decls.enter(sym); decls
145
+ }
146
+ case 2 => func2Applys.foldLeft(tp.decls.cloneScope) {
147
+ (decls, sym) => decls.enter(sym); decls
148
+ }
149
+ case _ => tp.decls
28
150
}
29
151
30
- val newDecls = sym.name.functionArity match {
31
- case 0 =>
32
- List (
33
- specApply(defn.UnitType , Nil ),
34
- specApply(defn.ByteType , Nil ),
35
- specApply(defn.ShortType , Nil ),
36
- specApply(defn.IntType , Nil ),
37
- specApply(defn.LongType , Nil ),
38
- specApply(defn.CharType , Nil ),
39
- specApply(defn.FloatType , Nil ),
40
- specApply(defn.DoubleType , Nil ),
41
- specApply(defn.BooleanType , Nil )
42
- )
43
- .foldLeft(tp.decls.cloneScope){ (decls, sym) => decls.enter(sym); decls }
152
+ tp.derivedClassInfo(decls = newDecls)
153
+ }
154
+ case _ => tp
155
+ }
44
156
45
- case 1 =>
46
- List (
47
- specApply(defn.UnitType , List (defn.IntType )),
48
- specApply(defn.IntType , List (defn.IntType )),
49
- specApply(defn.FloatType , List (defn.IntType )),
50
- specApply(defn.LongType , List (defn.IntType )),
51
- specApply(defn.DoubleType , List (defn.IntType )),
52
- specApply(defn.UnitType , List (defn.LongType )),
53
- specApply(defn.BooleanType , List (defn.LongType )),
54
- specApply(defn.IntType , List (defn.LongType )),
55
- specApply(defn.FloatType , List (defn.LongType )),
56
- specApply(defn.LongType , List (defn.LongType )),
57
- specApply(defn.DoubleType , List (defn.LongType )),
58
- specApply(defn.UnitType , List (defn.FloatType )),
59
- specApply(defn.BooleanType , List (defn.FloatType )),
60
- specApply(defn.IntType , List (defn.FloatType )),
61
- specApply(defn.FloatType , List (defn.FloatType )),
62
- specApply(defn.LongType , List (defn.FloatType )),
63
- specApply(defn.DoubleType , List (defn.FloatType )),
64
- specApply(defn.UnitType , List (defn.DoubleType )),
65
- specApply(defn.BooleanType , List (defn.DoubleType )),
66
- specApply(defn.IntType , List (defn.DoubleType )),
67
- specApply(defn.FloatType , List (defn.DoubleType )),
68
- specApply(defn.LongType , List (defn.DoubleType )),
69
- specApply(defn.DoubleType , List (defn.DoubleType ))
70
- )
71
- .foldLeft(tp.decls.cloneScope){ (decls, sym) => decls.enter(sym); decls }
157
+ /** Create bridge methods for FunctionN with specialized applys */
158
+ override def transformTemplate (tree : Template )(implicit ctx : Context , info : TransformerInfo ) = {
159
+ val owner = tree.symbol.owner
160
+ val additionalSymbols =
161
+ if (owner eq func0) func0Applys
162
+ else if (owner eq func1) func1Applys
163
+ else if (owner eq func2) func2Applys
164
+ else Nil
72
165
73
- case 2 =>
74
- List (
75
- specApply(defn.UnitType , List (defn.IntType , defn.IntType )),
76
- specApply(defn.BooleanType , List (defn.IntType , defn.IntType )),
77
- specApply(defn.IntType , List (defn.IntType , defn.IntType )),
78
- specApply(defn.FloatType , List (defn.IntType , defn.IntType )),
79
- specApply(defn.LongType , List (defn.IntType , defn.IntType )),
80
- specApply(defn.DoubleType , List (defn.IntType , defn.IntType )),
81
- specApply(defn.UnitType , List (defn.IntType , defn.LongType )),
82
- specApply(defn.BooleanType , List (defn.IntType , defn.LongType )),
83
- specApply(defn.IntType , List (defn.IntType , defn.LongType )),
84
- specApply(defn.FloatType , List (defn.IntType , defn.LongType )),
85
- specApply(defn.LongType , List (defn.IntType , defn.LongType )),
86
- specApply(defn.DoubleType , List (defn.IntType , defn.LongType )),
87
- specApply(defn.UnitType , List (defn.IntType , defn.DoubleType )),
88
- specApply(defn.BooleanType , List (defn.IntType , defn.DoubleType )),
89
- specApply(defn.IntType , List (defn.IntType , defn.DoubleType )),
90
- specApply(defn.FloatType , List (defn.IntType , defn.DoubleType )),
91
- specApply(defn.LongType , List (defn.IntType , defn.DoubleType )),
92
- specApply(defn.DoubleType , List (defn.IntType , defn.DoubleType )),
93
- specApply(defn.UnitType , List (defn.LongType , defn.IntType )),
94
- specApply(defn.BooleanType , List (defn.LongType , defn.IntType )),
95
- specApply(defn.IntType , List (defn.LongType , defn.IntType )),
96
- specApply(defn.FloatType , List (defn.LongType , defn.IntType )),
97
- specApply(defn.LongType , List (defn.LongType , defn.IntType )),
98
- specApply(defn.DoubleType , List (defn.LongType , defn.IntType )),
99
- specApply(defn.UnitType , List (defn.LongType , defn.LongType )),
100
- specApply(defn.BooleanType , List (defn.LongType , defn.LongType )),
101
- specApply(defn.IntType , List (defn.LongType , defn.LongType )),
102
- specApply(defn.FloatType , List (defn.LongType , defn.LongType )),
103
- specApply(defn.LongType , List (defn.LongType , defn.LongType )),
104
- specApply(defn.DoubleType , List (defn.LongType , defn.LongType )),
105
- specApply(defn.UnitType , List (defn.LongType , defn.DoubleType )),
106
- specApply(defn.BooleanType , List (defn.LongType , defn.DoubleType )),
107
- specApply(defn.IntType , List (defn.LongType , defn.DoubleType )),
108
- specApply(defn.FloatType , List (defn.LongType , defn.DoubleType )),
109
- specApply(defn.LongType , List (defn.LongType , defn.DoubleType )),
110
- specApply(defn.DoubleType , List (defn.LongType , defn.DoubleType )),
111
- specApply(defn.UnitType , List (defn.DoubleType , defn.IntType )),
112
- specApply(defn.BooleanType , List (defn.DoubleType , defn.IntType )),
113
- specApply(defn.IntType , List (defn.DoubleType , defn.IntType )),
114
- specApply(defn.FloatType , List (defn.DoubleType , defn.IntType )),
115
- specApply(defn.LongType , List (defn.DoubleType , defn.IntType )),
116
- specApply(defn.DoubleType , List (defn.DoubleType , defn.IntType )),
117
- specApply(defn.UnitType , List (defn.DoubleType , defn.LongType )),
118
- specApply(defn.BooleanType , List (defn.DoubleType , defn.LongType )),
119
- specApply(defn.IntType , List (defn.DoubleType , defn.LongType )),
120
- specApply(defn.FloatType , List (defn.DoubleType , defn.LongType )),
121
- specApply(defn.LongType , List (defn.DoubleType , defn.LongType )),
122
- specApply(defn.DoubleType , List (defn.DoubleType , defn.LongType )),
123
- specApply(defn.UnitType , List (defn.DoubleType , defn.DoubleType )),
124
- specApply(defn.BooleanType , List (defn.DoubleType , defn.DoubleType )),
125
- specApply(defn.IntType , List (defn.DoubleType , defn.DoubleType )),
126
- specApply(defn.FloatType , List (defn.DoubleType , defn.DoubleType )),
127
- specApply(defn.LongType , List (defn.DoubleType , defn.DoubleType )),
128
- specApply(defn.DoubleType , List (defn.DoubleType , defn.DoubleType ))
129
- )
130
- .foldLeft(tp.decls.cloneScope){ (decls, sym) => decls.enter(sym); decls }
166
+ if (additionalSymbols eq Nil ) tree
167
+ else {
168
+ val newBody : List [Tree ] = tree.body ++ additionalSymbols.map { applySym =>
169
+ polyDefDef(applySym.asTerm, tparams => vparamss => {
170
+ val prefix = This (owner.asClass).select(nme.apply).appliedToTypes(vparamss.head.map(_.tpe))
171
+ val argTypess = prefix.tpe.widen.paramTypess
131
172
132
- case _ =>
133
- tp.decls
173
+ val argss = Collections .map2(vparamss, argTypess) { (vparams, argTypes) =>
174
+ Collections .map2(vparams, argTypes) { (vparam, argType) => vparam.ensureConforms(argType) }
175
+ }
176
+ prefix.appliedToArgss(argss).ensureConforms(applySym.info.finalResultType)
177
+ })
134
178
}
135
179
136
- tp.derivedClassInfo(decls = newDecls )
180
+ cpy. Template (tree)(body = newBody )
137
181
}
138
- case _ => tp
139
182
}
140
183
}
0 commit comments