Skip to content

Commit b062aee

Browse files
committed
Handle Array.clone
1 parent 8691b26 commit b062aee

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
121121
val LongClass: Symbol = defn.LongClass
122122
val FloatClass: Symbol = defn.FloatClass
123123
val DoubleClass: Symbol = defn.DoubleClass
124-
val Array_clone: Symbol = defn.Array_clone
124+
def isArrayClone(tree: Tree) = tree match {
125+
case Select(qual, StdNames.nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true
126+
case _ => false
127+
}
128+
125129
val hashMethodSym: Symbol = NoSymbol // used to dispatch ## on primitives to ScalaRuntime.hash. Should be implemented by a miniphase
126130
val externalEqualsNumNum: Symbol = ctx.requiredMethod(BoxesRunTimeClass, nme.equalsNumNum)
127131
lazy val externalEqualsNumChar: Symbol = ??? // ctx.requiredMethod(BoxesRunTimeClass, nme.equalsNumChar) // this method is private
@@ -152,7 +156,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
152156

153157
def getPrimitive(sym: Symbol): Int = primitives.getPrimitive(sym)
154158

155-
def isPrimitive(sym: Symbol): Boolean = primitives.isPrimitive(sym)
159+
def isPrimitive(fun: Tree): Boolean = primitives.isPrimitive(fun)
156160
}
157161
implicit val TypeDefTag: ClassTag[TypeDef] = ClassTag[TypeDef](classOf[TypeDef])
158162
implicit val ApplyTag: ClassTag[Apply] = ClassTag[Apply](classOf[Apply])
@@ -434,7 +438,9 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
434438
isPrivate //|| (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass)
435439

436440
def isFinal: Boolean = sym is Flags.Final
437-
def isStaticMember: Boolean = (sym is Flags.JavaStatic) || (owner is Flags.ImplClass)
441+
def isStaticMember: Boolean = (sym ne NoSymbol) && ((sym is Flags.JavaStatic) || (owner is Flags.ImplClass))
442+
// guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone
443+
438444
def isBottomClass: Boolean = (sym ne defn.NullClass) && (sym ne defn.NothingClass)
439445
def isBridge: Boolean = sym is Flags.Bridge
440446
def isArtifact: Boolean = sym is Flags.Artifact

src/dotty/tools/backend/jvm/scalaPrimitives.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ package dotty.tools.dotc
77
package backend.jvm
88

99
import dotty.tools.backend.jvm.GenBCodePipeline
10-
import dotty.tools.dotc.ast.Trees.{Select, Apply}
11-
import dotty.tools.dotc.ast.tpd
10+
import dotty.tools.dotc.ast.Trees.Select
11+
import dotty.tools.dotc.ast.tpd._
1212
import dotty.tools.dotc.core.Names.TermName
13+
import dotty.tools.dotc.core.StdNames
1314
import dotty.tools.dotc.core.StdNames._
1415
import dotty.tools.dotc.core.Types.{JavaArrayType, ErrorType, Type}
1516

@@ -42,7 +43,6 @@ class DottyPrimitives(ctx: Context) {
4243

4344
/** Return the code for the given symbol. */
4445
def getPrimitive(sym: Symbol): Int = {
45-
assert(isPrimitive(sym), "Unknown primitive " + sym)
4646
primitives(sym)
4747
}
4848

@@ -55,7 +55,7 @@ class DottyPrimitives(ctx: Context) {
5555
* @param tpe The type of the receiver object. It is used only for array
5656
* operations
5757
*/
58-
def getPrimitive(app: tpd.Apply, tpe: Type)(implicit ctx: Context): Int = {
58+
def getPrimitive(app: Apply, tpe: Type)(implicit ctx: Context): Int = {
5959
val fun = app.fun.symbol
6060
val defn = ctx.definitions
6161
val code = app.fun match {
@@ -404,8 +404,13 @@ class DottyPrimitives(ctx: Context) {
404404
primitives.toMap
405405
}
406406

407-
def isPrimitive(sym: Symbol): Boolean = {
408-
(primitives contains sym) || sym == NoSymbol // the only trees that do not have a symbol assigned are array.{update,select,length}
407+
def isPrimitive(fun: Tree): Boolean = {
408+
(primitives contains fun.symbol(ctx)) ||
409+
(fun.symbol(ctx) == NoSymbol // the only trees that do not have a symbol assigned are array.{update,select,length,clone}}
410+
&& (fun match {
411+
case Select(_, StdNames.nme.clone_) => false // but array.clone is NOT a primitive op.
412+
case _ => true
413+
}))
409414
}
410415

411416
}

0 commit comments

Comments
 (0)