Improve Number.hashCode implementation in JavaScript
Fix KT-13577
This commit is contained in:
@@ -27,7 +27,7 @@ Kotlin.equals = function (obj1, obj2) {
|
|||||||
return obj2 !== obj2;
|
return obj2 !== obj2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof obj1 == "object" && typeof obj1.equals === "function") {
|
if (typeof obj1 === "object" && typeof obj1.equals === "function") {
|
||||||
return obj1.equals(obj2);
|
return obj1.equals(obj2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,16 +38,17 @@ Kotlin.hashCode = function (obj) {
|
|||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ("function" == typeof obj.hashCode) {
|
if ("function" === typeof obj.hashCode) {
|
||||||
return obj.hashCode();
|
return obj.hashCode();
|
||||||
}
|
}
|
||||||
var objType = typeof obj;
|
var objType = typeof obj;
|
||||||
if ("object" == objType || "function" == objType) {
|
if ("object" === objType || "function" === objType) {
|
||||||
return getObjectHashCode(obj);
|
return getObjectHashCode(obj);
|
||||||
} else if ("number" == objType) {
|
}
|
||||||
// TODO: a more elaborate code is needed for floating point values.
|
else if ("number" === objType) {
|
||||||
return obj | 0;
|
return numberHashCode(obj);
|
||||||
} if ("boolean" == objType) {
|
}
|
||||||
|
if ("boolean" === objType) {
|
||||||
return Number(obj)
|
return Number(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +56,39 @@ Kotlin.hashCode = function (obj) {
|
|||||||
return getStringHashCode(str);
|
return getStringHashCode(str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var numberHashCode;
|
||||||
|
|
||||||
|
if (typeof ArrayBuffer === "function") {
|
||||||
|
var bufferForNumberConversion = new ArrayBuffer(8);
|
||||||
|
var arrayForDoubleConversion = new Float64Array(bufferForNumberConversion);
|
||||||
|
var arrayForIntegerConversion = new Int32Array(bufferForNumberConversion);
|
||||||
|
|
||||||
|
// Detect endiannes of ArrayBuffer
|
||||||
|
var lowerIntegerIndex = 0;
|
||||||
|
var upperIntegerIndex = 1;
|
||||||
|
(function() {
|
||||||
|
arrayForDoubleConversion[0] = 1.2;
|
||||||
|
if (arrayForIntegerConversion[0] !== 0x3FF33333) {
|
||||||
|
lowerIntegerIndex = 1;
|
||||||
|
upperIntegerIndex = 0;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
numberHashCode = function(obj) {
|
||||||
|
if ((obj | 0) === obj) {
|
||||||
|
return obj | 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arrayForDoubleConversion[0] = obj;
|
||||||
|
return (arrayForIntegerConversion[lowerIntegerIndex] * 31 | 0) + arrayForIntegerConversion[upperIntegerIndex] | 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
numberHashCode = function(obj) {
|
||||||
|
return obj | 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Kotlin.toString = function (o) {
|
Kotlin.toString = function (o) {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return "null";
|
return "null";
|
||||||
|
|||||||
@@ -6275,6 +6275,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hashCode.kt")
|
||||||
|
public void testHashCode() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/hashCode.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("hexadecimalConstant.kt")
|
@TestMetadata("hexadecimalConstant.kt")
|
||||||
public void testHexadecimalConstant() throws Exception {
|
public void testHexadecimalConstant() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/hexadecimalConstant.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/hexadecimalConstant.kt");
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
fun box(): String {
|
||||||
|
|
||||||
|
|
||||||
|
var value = (3).hashCode()
|
||||||
|
if (value != 3) return "fail1: $value"
|
||||||
|
|
||||||
|
value = (3.14).hashCode()
|
||||||
|
if (value != 319176039) return "fail2: $value"
|
||||||
|
|
||||||
|
value = (3.14159).hashCode()
|
||||||
|
if (value != -1321819243) return "fail3: $value"
|
||||||
|
|
||||||
|
value = (1e80).hashCode()
|
||||||
|
if (value != 314940496) return "fail4: $value"
|
||||||
|
|
||||||
|
value = (1e81).hashCode()
|
||||||
|
if (value != 1519485350) return "fail5: $value"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user