[JS IR BE] Support super calls for methods of Any

This commit is contained in:
Svyatoslav Kuzmich
2018-08-03 18:27:05 +03:00
parent 439350d41a
commit a1c10956cb
9 changed files with 136 additions and 81 deletions
+43 -61
View File
@@ -6,11 +6,11 @@
package kotlin.js
fun equals(obj1: dynamic, obj2: dynamic): Boolean {
if (js("obj1 == null").unsafeCast<Boolean>()) {
return js("obj2 == null").unsafeCast<Boolean>();
if (obj1 == null) {
return obj2 == null
}
if (js("obj2 == null").unsafeCast<Boolean>()) {
return false;
if (obj2 == null) {
return false
}
return js("""
@@ -35,73 +35,55 @@ fun toString(o: dynamic): String = when {
else -> js("o.toString()").unsafeCast<String>()
}
// TODO: Simplify, extract kotlin declarations for inner helper functions
fun anyToString(o: dynamic): String = js("Object.prototype.toString.call(o)")
fun hashCode(obj: dynamic): Int {
return js(
"""
function hashCode(obj) {
if (obj == null) {
return 0;
}
var objType = typeof obj;
if ("object" === objType) {
return "function" === typeof obj.hashCode ? obj.hashCode() : getObjectHashCode(obj);
}
if ("function" === objType) {
return getObjectHashCode(obj);
}
if ("number" === objType) {
return getNumberHashCode(obj);
}
if ("boolean" === objType) {
return Number(obj)
}
if (obj == null)
return 0
var str = String(obj);
return getStringHashCode(str);
};
return when (typeOf(obj)) {
"object" -> if ("function" === js("typeof obj.hashCode")) js("obj.hashCode()") else getObjectHashCode(obj)
"function" -> getObjectHashCode(obj)
"number" -> getNumberHashCode(obj)
"boolean" -> if(obj.unsafeCast<Boolean>()) 1 else 0
else -> getStringHashCode(js("String(obj)"))
}
}
/** @const */
fun getObjectHashCode(obj: dynamic) = js("""
var POW_2_32 = 4294967296;
// TODO: consider switching to Symbol type once we are on ES6.
/** @const */
var OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue${"$"}";
var byteBuffer = new ArrayBuffer(8);
var bufFloat64 = new Float64Array(byteBuffer);
var bufInt32 = new Int32Array(byteBuffer);
function getObjectHashCode(obj) {
if (!(OBJECT_HASH_CODE_PROPERTY_NAME in obj)) {
var hash = (Math.random() * POW_2_32) | 0; // Make 32-bit singed integer.
Object.defineProperty(obj, OBJECT_HASH_CODE_PROPERTY_NAME, { value: hash, enumerable: false });
}
return obj[OBJECT_HASH_CODE_PROPERTY_NAME];
if (!(OBJECT_HASH_CODE_PROPERTY_NAME in obj)) {
var hash = (Math.random() * POW_2_32) | 0; // Make 32-bit singed integer.
Object.defineProperty(obj, OBJECT_HASH_CODE_PROPERTY_NAME, { value: hash, enumerable: false });
}
return obj[OBJECT_HASH_CODE_PROPERTY_NAME];
""").unsafeCast<Int>();
function getStringHashCode(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
var code = str.charCodeAt(i);
hash = (hash * 31 + code) | 0; // Keep it 32-bit.
}
return hash;
fun getStringHashCode(str: String): Int {
var hash = 0
val length: Int = js("str.length") // TODO: Implement WString.length
for (i in 0..length-1) {
val code: Int = js("str.charCodeAt(i)")
hash = hash * 31 + code
}
function getNumberHashCode(obj) {
if ((obj | 0) === obj) {
return obj | 0;
}
else {
bufFloat64[0] = obj;
return (bufInt32[1] * 31 | 0) + bufInt32[0] | 0;
}
}
return hashCode(obj);
"""
).unsafeCast<Int>()
return hash
}
fun getNumberHashCode(obj: dynamic) = js("""
if ((obj | 0) === obj) {
return obj | 0;
}
else {
var byteBuffer = new ArrayBuffer (8);
var bufFloat64 = new Float64Array (byteBuffer);
var bufInt32 = new Int32Array (byteBuffer);
bufFloat64[0] = obj;
return (bufInt32[1] * 31 | 0)+bufInt32[0] | 0;
}
""").unsafeCast<Int>()
// TODO: Use getObjectHashCode instead
fun identityHashCode(obj: dynamic): Int = hashCode(obj)