1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package std.core; 17 18export final class Runtime { 19 internal constructor() {} 20 21 /** 22 * Returns a hash code for the Object. 23 * 24 * @param o to calculate hash code from 25 * 26 * @returns hash code 27 */ 28 public native getHashCode(o: Object): int; 29 30 /** 31 * Checks if two items are equal. 32 * 33 * @param o1 first object to compare 34 * 35 * @param o2 second object to compare 36 * 37 * @returns true if items are equal 38 */ 39 public equals(o1: NullishType, o2: NullishType): boolean { 40 if (this.isSameReference(o1, null)) { 41 return this.isSameReference(o2, null) 42 } 43 if (this.isSameReference(o1, undefined)) { 44 return this.isSameReference(o2, undefined) 45 } 46 if (this.isSameReference(o2, null) || this.isSameReference(o2, undefined)) { 47 return false; 48 } 49 50 return o1 == o2 51 } 52 53 /** 54 * Checks if two items are equal 'by value' 55 * 56 * @param o1 first object to compare 57 * 58 * @param o2 second object to compare 59 * 60 * @returns true if items are equal 'by value' 61 */ 62 public sameValue(o1: NullishType, o2: NullishType): boolean { 63 if (this.isSameReference(o1, null)) { 64 return this.isSameReference(o2, null) 65 } 66 if (this.isSameReference(o1, undefined)) { 67 return this.isSameReference(o2, undefined) 68 } 69 if (this.isSameReference(o2, null) || this.isSameReference(o2, undefined)) { 70 return false; 71 } 72 73 if (o1 instanceof Number && o2 instanceof Number) { 74 return this.sameNumberValue(o1 as Number, o2 as Number) 75 } else if (o1 instanceof Float && o2 instanceof Float) { 76 return this.sameFloatValue(o1 as Float, o2 as Float) 77 } 78 79 return o1 == o2 80 } 81 82 private sameNumberValue(n1: Number, n2: Number): boolean { 83 const n1val = n1.valueOf() 84 const n2val = n2.valueOf() 85 if (n1val == 0 || n2val == 0) { 86 return Double.bitCastToLong(n1val) == Double.bitCastToLong(n2val); 87 } 88 if (isNaN(n1val) != isNaN(n2val)) { 89 return false; 90 } else if (isNaN(n1val)) { 91 return true; 92 } else { 93 return n1val == n2val 94 } 95 } 96 97 private sameFloatValue(f1: Float, f2: Float): boolean { 98 const f1val = f1.unboxed() 99 const f2val = f2.unboxed() 100 101 if (f1val == 0 || f2val == 0) { 102 return Float.bitCastToInt(f1val) == Float.bitCastToInt(f2val) 103 } 104 105 if (isNaN(f1val) != isNaN(f2val)) { 106 return false 107 } else if (isNaN(f1val)) { 108 return true 109 } else { 110 return f1val == f2val 111 } 112 } 113 114 public sameValueZero(o1: NullishType, o2: NullishType): boolean { 115 if (this.sameValue(o1, o2)) { 116 return true; 117 } 118 if (o1 instanceof Number && o2 instanceof Number) { 119 const n1 = (o1 as Number).valueOf() 120 const n2 = (o2 as Number).valueOf() 121 return n1 == 0 && n2 == 0; 122 } 123 return false; 124 } 125 126 /** 127 * Checks if two references point to a same object/value. 128 * 129 * @param o1 first object to compare 130 * 131 * @param o2 second object to compare 132 * 133 * @returns true if Objects are equal 134 */ 135 public native isSameReference(o1: NullishType, o2: NullishType): boolean; 136 137 /** 138 * Internal entrypoint to create exception for failed type cast 139 * 140 * @param src source value 141 * 142 * @param dstStr target type string 143 * 144 * @returns exception object to throw 145 */ 146 internal static failedTypeCastException(src: NullishType, dstStr: string): ClassCastError { 147 let srcStr = src === null ? "null" : 148 (src === undefined ? "undefined" : 149 TypeAPIGetTypeDescriptor(src)); 150 return new ClassCastError(srcStr + " cannot be cast to " + dstStr); 151 } 152 153 /** 154 * Return a string with the name of the type kind of the object 155 * 156 * @param o an object 157 * 158 * @returns a string with the name of the type kind of the object 159 */ 160 internal native static typeOf(o: Object): String; 161} 162 163export const runtime = new Runtime(); 164 165export function __runtimeEquals(o1: NullishType, o2: NullishType): boolean { 166 return runtime.equals(o1, o2) 167} 168 169export function __runtimeSameValueZero(o1: NullishType, o2: NullishType): boolean { 170 return runtime.sameValueZero(o1, o2) 171} 172 173export function __runtimeSameValue(o1: NullishType, o2: NullishType): boolean { 174 return runtime.sameValue(o1, o2) 175} 176 177export function __runtimeIsSameReference(o1: NullishType, o2: NullishType): boolean { 178 return runtime.isSameReference(o1, o2) 179} 180