Skip to content

Commit 2b59eaf

Browse files
committed
Squash: Emit some of our unsigned ops directly in the javalib.
1 parent e46ca69 commit 2b59eaf

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,8 +2780,8 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
27802780
* But must be replaced by the tail-jump-this local variable if there
27812781
* is one.
27822782
*/
2783-
private def genThis()(implicit pos: Position): js.Tree = {
2784-
thisLocalVarName.fold[js.Tree] {
2783+
private def genThis()(implicit pos: Position): js.VarRef = {
2784+
thisLocalVarName.fold[js.VarRef] {
27852785
if (isJSFunctionDef(currentClassSym)) {
27862786
abort(
27872787
"Unexpected `this` reference inside the body of a JS function class: " +
@@ -7359,7 +7359,7 @@ private object GenJSCode {
73597359

73607360
private abstract class JavalibOpBody {
73617361
/** Generates the body of this special method, given references to the receiver and parameters. */
7362-
def generate(receiver: js.Tree, args: List[js.Tree])(implicit pos: ir.Position): js.Tree
7362+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree
73637363
}
73647364

73657365
private object JavalibOpBody {
@@ -7373,35 +7373,51 @@ private object GenJSCode {
73737373

73747374
/** UnaryOp applying to the `this` parameter. */
73757375
final case class ThisUnaryOp(op: js.UnaryOp.Code) extends JavalibOpBody {
7376-
def generate(receiver: js.Tree, args: List[js.Tree])(implicit pos: ir.Position): js.Tree = {
7376+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree = {
73777377
assert(args.isEmpty)
73787378
js.UnaryOp(op, receiver)
73797379
}
73807380
}
73817381

73827382
/** BinaryOp applying to the `this` parameter and the regular parameter. */
73837383
final case class ThisBinaryOp(op: js.BinaryOp.Code, checkNulls: Boolean = false) extends JavalibOpBody {
7384-
def generate(receiver: js.Tree, args: List[js.Tree])(implicit pos: ir.Position): js.Tree = {
7384+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree = {
73857385
val List(rhs) = args: @unchecked
73867386
js.BinaryOp(op, receiver, checkNotNullIf(rhs, checkNulls))
73877387
}
73887388
}
73897389

73907390
/** UnaryOp applying to the only regular parameter (`this` is ignored). */
73917391
final case class ArgUnaryOp(op: js.UnaryOp.Code, checkNulls: Boolean = false) extends JavalibOpBody {
7392-
def generate(receiver: js.Tree, args: List[js.Tree])(implicit pos: ir.Position): js.Tree = {
7392+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree = {
73937393
val List(arg) = args: @unchecked
73947394
js.UnaryOp(op, checkNotNullIf(arg, checkNulls))
73957395
}
73967396
}
73977397

7398-
/** BinaryOp applying to the two regular paramters (`this` is ignored). */
7398+
/** BinaryOp applying to the two regular parameters (`this` is ignored). */
73997399
final case class ArgBinaryOp(op: js.BinaryOp.Code, checkNulls: Boolean = false) extends JavalibOpBody {
7400-
def generate(receiver: js.Tree, args: List[js.Tree])(implicit pos: ir.Position): js.Tree = {
7400+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree = {
74017401
val List(lhs, rhs) = args: @unchecked
74027402
js.BinaryOp(op, checkNotNullIf(lhs, checkNulls), checkNotNullIf(rhs, checkNulls))
74037403
}
74047404
}
7405+
7406+
/** Body of a `compare` method, with a less-than and an equal operator. */
7407+
final case class ArgCompareOp(ltOp: js.BinaryOp.Code, eqOp: js.BinaryOp.Code) extends JavalibOpBody {
7408+
def generate(receiver: js.VarRef, args: List[js.VarRef])(implicit pos: ir.Position): js.Tree = {
7409+
val List(lhs, rhs) = args: @unchecked
7410+
js.If(
7411+
js.BinaryOp(ltOp, lhs, rhs),
7412+
js.IntLiteral(-1),
7413+
js.If(
7414+
js.BinaryOp(eqOp, lhs, rhs),
7415+
js.IntLiteral(0),
7416+
js.IntLiteral(1)
7417+
)(jstpe.IntType)
7418+
)(jstpe.IntType)
7419+
}
7420+
}
74057421
}
74067422

74077423
/** Methods of the javalib whose body must be replaced by a dedicated
@@ -7425,11 +7441,14 @@ private object GenJSCode {
74257441

74267442
val byClass: Map[ClassName, Map[MethodName, JavalibOpBody]] = Map(
74277443
jswkn.BoxedIntegerClass.withSuffix("$") -> Map(
7444+
m("compareUnsigned", List(I, I), I) -> ArgCompareOp(binop.Int_unsigned_<, binop.Int_==),
7445+
m("toUnsignedLong", List(I), J) -> ArgUnaryOp(unop.UnsignedIntToLong),
74287446
m("divideUnsigned", List(I, I), I) -> ArgBinaryOp(binop.Int_unsigned_/),
74297447
m("remainderUnsigned", List(I, I), I) -> ArgBinaryOp(binop.Int_unsigned_%),
74307448
m("numberOfLeadingZeros", List(I), I) -> ArgUnaryOp(unop.Int_clz)
74317449
),
74327450
jswkn.BoxedLongClass.withSuffix("$") -> Map(
7451+
m("compareUnsigned", List(J, J), I) -> ArgCompareOp(binop.Long_unsigned_<, binop.Long_==),
74337452
m("divideUnsigned", List(J, J), J) -> ArgBinaryOp(binop.Long_unsigned_/),
74347453
m("remainderUnsigned", List(J, J), J) -> ArgBinaryOp(binop.Long_unsigned_%),
74357454
m("numberOfLeadingZeros", List(J), I) -> ArgUnaryOp(unop.Long_clz)

javalib/src/main/scala/java/lang/Integer.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,11 @@ object Integer {
189189
@inline def compare(x: scala.Int, y: scala.Int): scala.Int =
190190
if (x == y) 0 else if (x < y) -1 else 1
191191

192-
@inline def compareUnsigned(x: scala.Int, y: scala.Int): scala.Int = {
193-
import Utils.toUint
194-
if (x == y) 0
195-
else if (toUint(x) > toUint(y)) 1
196-
else -1
197-
}
192+
@inline def compareUnsigned(x: scala.Int, y: scala.Int): scala.Int =
193+
throw new Error("stub") // body replaced by the compiler back-end
198194

199195
@inline def toUnsignedLong(x: Int): scala.Long =
200-
x.toLong & 0xffffffffL
196+
throw new Error("stub") // body replaced by the compiler back-end
201197

202198
// Wasm intrinsic
203199
def bitCount(i: scala.Int): scala.Int = {

javalib/src/main/scala/java/lang/Long.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,16 +337,16 @@ object Long {
337337
@inline def hashCode(value: scala.Long): Int =
338338
value.toInt ^ (value >>> 32).toInt
339339

340-
// Intrinsic
340+
// RuntimeLong intrinsic
341341
@inline def compare(x: scala.Long, y: scala.Long): scala.Int = {
342342
if (x == y) 0
343343
else if (x < y) -1
344344
else 1
345345
}
346346

347-
// TODO Intrinsic?
347+
// TODO RuntimeLong intrinsic?
348348
@inline def compareUnsigned(x: scala.Long, y: scala.Long): scala.Int =
349-
compare(x ^ SignBit, y ^ SignBit)
349+
throw new Error("stub") // body replaced by the compiler back-end
350350

351351
@inline def divideUnsigned(dividend: scala.Long, divisor: scala.Long): scala.Long =
352352
throw new Error("stub") // body replaced by the compiler back-end

0 commit comments

Comments
 (0)