Skip to content

Commit c451553

Browse files
authored
Merge pull request #219 from scala/backport-lts-3.3-22446
Backport "Scala.js: Emit `js.NewArray` IR nodes when possible." to 3.3 LTS
2 parents c74a752 + 42a5667 commit c451553

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala

+24
Original file line numberDiff line numberDiff line change
@@ -2553,6 +2553,8 @@ class JSCodeGen()(using genCtx: Context) {
25532553
genCoercion(tree, receiver, code)
25542554
else if (code == JSPrimitives.THROW)
25552555
genThrow(tree, args)
2556+
else if (code == JSPrimitives.NEW_ARRAY)
2557+
genNewArray(tree, args)
25562558
else if (JSPrimitives.isJSPrimitive(code))
25572559
genJSPrimitive(tree, args, code, isStat)
25582560
else
@@ -3022,6 +3024,24 @@ class JSCodeGen()(using genCtx: Context) {
30223024
}
30233025
}
30243026

3027+
/** Gen a call to the special `newArray` method. */
3028+
private def genNewArray(tree: Apply, args: List[Tree]): js.Tree = {
3029+
implicit val pos: SourcePosition = tree.sourcePos
3030+
3031+
val List(elemClazz, Literal(arrayClassConstant), dimsArray: JavaSeqLiteral) = args: @unchecked
3032+
3033+
dimsArray.elems match {
3034+
case singleDim :: Nil =>
3035+
// Use a js.NewArray
3036+
val arrayTypeRef = toTypeRef(arrayClassConstant.typeValue).asInstanceOf[jstpe.ArrayTypeRef]
3037+
js.NewArray(arrayTypeRef, List(genExpr(singleDim)))
3038+
case _ =>
3039+
// Delegate to jlr.Array.newInstance
3040+
js.ApplyStatic(js.ApplyFlags.empty, JLRArrayClassName, js.MethodIdent(JLRArrayNewInstanceMethodName),
3041+
List(genExpr(elemClazz), genJavaSeqLiteral(dimsArray)))(jstpe.AnyType)
3042+
}
3043+
}
3044+
30253045
/** Gen a "normal" apply (to a true method).
30263046
*
30273047
* But even these are further refined into:
@@ -4835,6 +4855,7 @@ class JSCodeGen()(using genCtx: Context) {
48354855
object JSCodeGen {
48364856

48374857
private val NullPointerExceptionClass = ClassName("java.lang.NullPointerException")
4858+
private val JLRArrayClassName = ClassName("java.lang.reflect.Array")
48384859
private val JSObjectClassName = ClassName("scala.scalajs.js.Object")
48394860
private val JavaScriptExceptionClassName = ClassName("scala.scalajs.js.JavaScriptException")
48404861

@@ -4844,6 +4865,9 @@ object JSCodeGen {
48444865

48454866
private val selectedValueMethodName = MethodName("selectedValue", Nil, ObjectClassRef)
48464867

4868+
private val JLRArrayNewInstanceMethodName =
4869+
MethodName("newInstance", List(jstpe.ClassRef(jsNames.ClassClass), jstpe.ArrayTypeRef(jstpe.IntRef, 1)), ObjectClassRef)
4870+
48474871
private val ObjectArgConstructorName = MethodName.constructor(List(ObjectClassRef))
48484872

48494873
private val thisOriginalName = OriginalName("this")

compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ object JSPrimitives {
4848
inline val UNWRAP_FROM_THROWABLE = WRAP_AS_THROWABLE + 1 // js.special.unwrapFromThrowable
4949
inline val DEBUGGER = UNWRAP_FROM_THROWABLE + 1 // js.special.debugger
5050

51-
inline val THROW = DEBUGGER + 1
51+
inline val THROW = DEBUGGER + 1 // <special-ops>.throw
52+
inline val NEW_ARRAY = THROW + 1 // scala.runtime.Arrays.newArray
5253

53-
inline val UNION_FROM = THROW + 1 // js.|.from
54+
inline val UNION_FROM = NEW_ARRAY + 1 // js.|.from
5455
inline val UNION_FROM_TYPE_CONSTRUCTOR = UNION_FROM + 1 // js.|.fromTypeConstructor
5556

5657
inline val REFLECT_SELECTABLE_SELECTDYN = UNION_FROM_TYPE_CONSTRUCTOR + 1 // scala.reflect.Selectable.selectDynamic
@@ -137,6 +138,7 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
137138
addPrimitive(jsdefn.Special_debugger, DEBUGGER)
138139

139140
addPrimitive(defn.throwMethod, THROW)
141+
addPrimitive(defn.newArrayMethod, NEW_ARRAY)
140142

141143
addPrimitive(jsdefn.PseudoUnion_from, UNION_FROM)
142144
addPrimitive(jsdefn.PseudoUnion_fromTypeConstructor, UNION_FROM_TYPE_CONSTRUCTOR)

compiler/src/dotty/tools/dotc/core/Types.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -5794,11 +5794,13 @@ object Types extends TypeUtils {
57945794
protected def derivedLambdaType(tp: LambdaType)(formals: List[tp.PInfo], restpe: Type): Type =
57955795
tp.derivedLambdaType(tp.paramNames, formals, restpe)
57965796

5797+
protected def mapArg(arg: Type, tparam: ParamInfo): Type = arg match
5798+
case arg: TypeBounds => this(arg)
5799+
case arg => atVariance(variance * tparam.paramVarianceSign)(this(arg))
5800+
57975801
protected def mapArgs(args: List[Type], tparams: List[ParamInfo]): List[Type] = args match
57985802
case arg :: otherArgs if tparams.nonEmpty =>
5799-
val arg1 = arg match
5800-
case arg: TypeBounds => this(arg)
5801-
case arg => atVariance(variance * tparams.head.paramVarianceSign)(this(arg))
5803+
val arg1 = mapArg(arg, tparams.head)
58025804
val otherArgs1 = mapArgs(otherArgs, tparams.tail)
58035805
if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
58045806
else arg1 :: otherArgs1

presentation-compiler/src/main/dotty/tools/pc/utils/InteractiveEnrichments.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ object InteractiveEnrichments extends CommonMtagsEnrichments:
281281
sym,
282282
() => parentSymbols.iterator.map(toSemanticdbSymbol).toList.asJava,
283283
contentType,
284-
)
284+
).nn
285285
documentation.nn.toScala
286286
end symbolDocumentation
287287
end extension

0 commit comments

Comments
 (0)