@@ -5914,10 +5914,26 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
5914
5914
*/
5915
5915
for ((arg, wasRepeated) <- args.zipAll(wereRepeated, EmptyTree , false )) yield {
5916
5916
if (wasRepeated) {
5917
- tryGenRepeatedParamAsJSArray(arg, handleNil = false ).fold {
5918
- genExpr(arg)
5919
- } { genArgs =>
5920
- genJSArrayToVarArgs(js.JSArrayConstr (genArgs))
5917
+ /* If the argument is a call to the compiler's chosen `wrapArray`
5918
+ * method with an array literal as argument, we know it actually
5919
+ * came from expanded varargs. In that case, rewrite to calling our
5920
+ * custom `ScalaRunTime.to*VarArgs` method. These methods choose
5921
+ * the best implementation of varargs depending on the target
5922
+ * platform.
5923
+ */
5924
+ arg match {
5925
+ case MaybeAsInstanceOf (wrapArray @ WrapArray (
5926
+ MaybeAsInstanceOf (arrayValue : ArrayValue ))) =>
5927
+ implicit val pos = wrapArray.pos
5928
+ js.Apply (
5929
+ js.ApplyFlags .empty,
5930
+ genLoadModule(ScalaRunTimeModule ),
5931
+ js.MethodIdent (WrapArray .wrapArraySymToToVarArgsName(wrapArray.symbol)),
5932
+ List (genExpr(arrayValue))
5933
+ )(jstpe.ClassType (encodeClassName(SeqClass ), nullable = true ))
5934
+
5935
+ case _ =>
5936
+ genExpr(arg)
5921
5937
}
5922
5938
} else {
5923
5939
genExpr(arg)
@@ -6069,27 +6085,6 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6069
6085
* Otherwise, it returns a JSSpread with the Seq converted to a js.Array.
6070
6086
*/
6071
6087
private def genPrimitiveJSRepeatedParam (arg : Tree ): List [js.TreeOrJSSpread ] = {
6072
- tryGenRepeatedParamAsJSArray(arg, handleNil = true ) getOrElse {
6073
- /* Fall back to calling runtime.toJSVarArgs to perform the conversion
6074
- * to js.Array, then wrap in a Spread operator.
6075
- */
6076
- implicit val pos = arg.pos
6077
- val jsArrayArg = genApplyMethod(
6078
- genLoadModule(RuntimePackageModule ),
6079
- Runtime_toJSVarArgs ,
6080
- List (genExpr(arg)))
6081
- List (js.JSSpread (jsArrayArg))
6082
- }
6083
- }
6084
-
6085
- /** Try and expand a repeated param (xs: T*) at compile-time.
6086
- * This method recognizes the shapes of tree generated by the desugaring
6087
- * of repeated params in Scala, and expands them.
6088
- * If `arg` does not have the shape of a generated repeated param, this
6089
- * method returns `None`.
6090
- */
6091
- private def tryGenRepeatedParamAsJSArray (arg : Tree ,
6092
- handleNil : Boolean ): Option [List [js.Tree ]] = {
6093
6088
implicit val pos = arg.pos
6094
6089
6095
6090
// Given a method `def foo(args: T*)`
@@ -6101,15 +6096,22 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6101
6096
* the type before erasure.
6102
6097
*/
6103
6098
val elemTpe = tpt.tpe
6104
- Some ( elems.map(e => ensureBoxed(genExpr(e), elemTpe) ))
6099
+ elems.map(e => ensureBoxed(genExpr(e), elemTpe))
6105
6100
6106
6101
// foo()
6107
- case Select (_, _) if handleNil && arg.symbol == NilModule =>
6108
- Some ( Nil )
6102
+ case Select (_, _) if arg.symbol == NilModule =>
6103
+ Nil
6109
6104
6110
6105
// foo(argSeq:_*) - cannot be optimized
6111
6106
case _ =>
6112
- None
6107
+ /* Fall back to calling runtime.toJSVarArgs to perform the conversion
6108
+ * to js.Array, then wrap in a Spread operator.
6109
+ */
6110
+ val jsArrayArg = genApplyMethod(
6111
+ genLoadModule(RuntimePackageModule ),
6112
+ Runtime_toJSVarArgs ,
6113
+ List (genExpr(arg)))
6114
+ List (js.JSSpread (jsArrayArg))
6113
6115
}
6114
6116
}
6115
6117
@@ -6137,25 +6139,36 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6137
6139
def isClassTagBasedWrapArrayMethod (sym : Symbol ): Boolean =
6138
6140
sym == wrapRefArrayMethod || sym == genericWrapArrayMethod
6139
6141
6140
- private val isWrapArray : Set [Symbol ] = {
6141
- Seq (
6142
- nme.wrapRefArray,
6143
- nme.wrapByteArray,
6144
- nme.wrapShortArray,
6145
- nme.wrapCharArray,
6146
- nme.wrapIntArray,
6147
- nme.wrapLongArray,
6148
- nme.wrapFloatArray,
6149
- nme.wrapDoubleArray,
6150
- nme.wrapBooleanArray,
6151
- nme.wrapUnitArray,
6152
- nme.genericWrapArray
6153
- ).map(getMemberMethod(wrapArrayModule, _)).toSet
6142
+ val wrapArraySymToToVarArgsName : Map [Symbol , MethodName ] = {
6143
+ val SeqClassRef = jstpe.ClassRef (encodeClassName(SeqClass ))
6144
+
6145
+ def make (simpleName : String , argTypeRef : jstpe.TypeRef ): MethodName =
6146
+ MethodName (simpleName, argTypeRef :: Nil , SeqClassRef )
6147
+
6148
+ val items : Seq [(Name , String , jstpe.TypeRef )] = Seq (
6149
+ (nme.genericWrapArray, " toGenericVarArgs" , jswkn.ObjectRef ),
6150
+ (nme.wrapRefArray, " toRefVarArgs" , jstpe.ArrayTypeRef (jswkn.ObjectRef , 1 )),
6151
+ (nme.wrapUnitArray, " toUnitVarArgs" , jstpe.ArrayTypeRef (jstpe.ClassRef (jswkn.BoxedUnitClass ), 1 )),
6152
+ (nme.wrapBooleanArray, " toBooleanVarArgs" , jstpe.ArrayTypeRef (jstpe.BooleanRef , 1 )),
6153
+ (nme.wrapCharArray, " toCharVarArgs" , jstpe.ArrayTypeRef (jstpe.CharRef , 1 )),
6154
+ (nme.wrapByteArray, " toByteVarArgs" , jstpe.ArrayTypeRef (jstpe.ByteRef , 1 )),
6155
+ (nme.wrapShortArray, " toShortVarArgs" , jstpe.ArrayTypeRef (jstpe.ShortRef , 1 )),
6156
+ (nme.wrapIntArray, " toIntVarArgs" , jstpe.ArrayTypeRef (jstpe.IntRef , 1 )),
6157
+ (nme.wrapLongArray, " toLongVarArgs" , jstpe.ArrayTypeRef (jstpe.LongRef , 1 )),
6158
+ (nme.wrapFloatArray, " toFloatVarArgs" , jstpe.ArrayTypeRef (jstpe.FloatRef , 1 )),
6159
+ (nme.wrapDoubleArray, " toDoubleVarArgs" , jstpe.ArrayTypeRef (jstpe.DoubleRef , 1 ))
6160
+ )
6161
+
6162
+ items.map { case (wrapArrayName, simpleName, argTypeRef) =>
6163
+ val wrapArraySym = getMemberMethod(wrapArrayModule, wrapArrayName)
6164
+ val toVarArgsName = MethodName (simpleName, argTypeRef :: Nil , SeqClassRef )
6165
+ wrapArraySym -> toVarArgsName
6166
+ }.toMap
6154
6167
}
6155
6168
6156
6169
def unapply (tree : Apply ): Option [Tree ] = tree match {
6157
6170
case Apply (wrapArray_?, List (wrapped))
6158
- if isWrapArray (wrapArray_?.symbol) =>
6171
+ if wrapArraySymToToVarArgsName.contains (wrapArray_?.symbol) =>
6159
6172
Some (wrapped)
6160
6173
case _ =>
6161
6174
None
0 commit comments