14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/linked_hash_table.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/js_object-inl.h"
194514f5e3Sopenharmony_ci
204514f5e3Sopenharmony_cinamespace panda::ecmascript {
214514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
224514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::Create(const JSThread *thread,
234514f5e3Sopenharmony_ci    int numberOfElements, MemSpaceKind spaceKind)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    ASSERT_PRINT(numberOfElements > 0, "size must be a non-negative integer");
264514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
274514f5e3Sopenharmony_ci    auto capacity = static_cast<uint32_t>(numberOfElements);
284514f5e3Sopenharmony_ci    ASSERT_PRINT(helpers::math::IsPowerOfTwo(capacity), "capacity must be pow of '2'");
294514f5e3Sopenharmony_ci    int length = ELEMENTS_START_INDEX + numberOfElements + numberOfElements * (HashObject::ENTRY_SIZE + 1);
304514f5e3Sopenharmony_ci    JSHandle<Derived> table;
314514f5e3Sopenharmony_ci    if (spaceKind == MemSpaceKind::SHARED) {
324514f5e3Sopenharmony_ci        table = JSHandle<Derived>(factory->NewSOldSpaceTaggedArray(length));
334514f5e3Sopenharmony_ci    } else {
344514f5e3Sopenharmony_ci        table = JSHandle<Derived>(factory->NewTaggedArray(length));
354514f5e3Sopenharmony_ci    }
364514f5e3Sopenharmony_ci    table->SetNumberOfElements(thread, 0);
374514f5e3Sopenharmony_ci    table->SetNumberOfDeletedElements(thread, 0);
384514f5e3Sopenharmony_ci    table->SetCapacity(thread, capacity);
394514f5e3Sopenharmony_ci    return table;
404514f5e3Sopenharmony_ci}
414514f5e3Sopenharmony_ci
424514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
434514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::Insert(const JSThread *thread, const JSHandle<Derived> &table,
444514f5e3Sopenharmony_ci                                                               const JSHandle<JSTaggedValue> &key,
454514f5e3Sopenharmony_ci                                                               const JSHandle<JSTaggedValue> &value)
464514f5e3Sopenharmony_ci{
474514f5e3Sopenharmony_ci    ASSERT(IsKey(key.GetTaggedValue()));
484514f5e3Sopenharmony_ci    int hash = LinkedHash::Hash(thread, key.GetTaggedValue());
494514f5e3Sopenharmony_ci    int entry = table->FindElement(thread, key.GetTaggedValue());
504514f5e3Sopenharmony_ci    if (entry != -1) {
514514f5e3Sopenharmony_ci        table->SetValue(thread, entry, value.GetTaggedValue());
524514f5e3Sopenharmony_ci        return table;
534514f5e3Sopenharmony_ci    }
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ci    JSHandle<Derived> newTable = GrowCapacity(thread, table);
564514f5e3Sopenharmony_ci
574514f5e3Sopenharmony_ci    uint32_t bucket = newTable->HashToBucket(hash);
584514f5e3Sopenharmony_ci    entry = newTable->NumberOfElements() + newTable->NumberOfDeletedElements();
594514f5e3Sopenharmony_ci    newTable->InsertNewEntry(thread, bucket, entry);
604514f5e3Sopenharmony_ci    newTable->SetKey(thread, entry, key.GetTaggedValue());
614514f5e3Sopenharmony_ci    newTable->SetValue(thread, entry, value.GetTaggedValue());
624514f5e3Sopenharmony_ci    newTable->SetNumberOfElements(thread, newTable->NumberOfElements() + 1);
634514f5e3Sopenharmony_ci
644514f5e3Sopenharmony_ci    return newTable;
654514f5e3Sopenharmony_ci}
664514f5e3Sopenharmony_ci
674514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
684514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::InsertWeakRef(const JSThread *thread,
694514f5e3Sopenharmony_ci    const JSHandle<Derived> &table, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)
704514f5e3Sopenharmony_ci{
714514f5e3Sopenharmony_ci    ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE;
724514f5e3Sopenharmony_ci    ASSERT(IsKey(key.GetTaggedValue()));
734514f5e3Sopenharmony_ci    int hash = LinkedHash::Hash(thread, key.GetTaggedValue());
744514f5e3Sopenharmony_ci    int entry = table->FindElement(thread, key.GetTaggedValue());
754514f5e3Sopenharmony_ci    if (entry != -1) {
764514f5e3Sopenharmony_ci        table->SetValue(thread, entry, value.GetTaggedValue());
774514f5e3Sopenharmony_ci        return table;
784514f5e3Sopenharmony_ci    }
794514f5e3Sopenharmony_ci
804514f5e3Sopenharmony_ci    JSHandle<Derived> newTable = GrowCapacity(thread, table);
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ci    uint32_t bucket = newTable->HashToBucket(hash);
834514f5e3Sopenharmony_ci    entry = newTable->NumberOfElements() + newTable->NumberOfDeletedElements();
844514f5e3Sopenharmony_ci    newTable->InsertNewEntry(thread, bucket, entry);
854514f5e3Sopenharmony_ci    JSTaggedValue weakKey(key->CreateAndGetWeakRef());
864514f5e3Sopenharmony_ci    newTable->SetKey(thread, entry, weakKey);
874514f5e3Sopenharmony_ci    // The ENTRY_VALUE_INDEX of LinkedHashSet is 0. SetValue will cause the overwitten key.
884514f5e3Sopenharmony_ci    if (std::is_same_v<LinkedHashMap, Derived>) {
894514f5e3Sopenharmony_ci        newTable->SetValue(thread, entry, value.GetTaggedValue());
904514f5e3Sopenharmony_ci    }
914514f5e3Sopenharmony_ci    newTable->SetNumberOfElements(thread, newTable->NumberOfElements() + 1);
924514f5e3Sopenharmony_ci
934514f5e3Sopenharmony_ci    return newTable;
944514f5e3Sopenharmony_ci}
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
974514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::GrowCapacity(const JSThread *thread,
984514f5e3Sopenharmony_ci    const JSHandle<Derived> &table, int numberOfAddedElements)
994514f5e3Sopenharmony_ci{
1004514f5e3Sopenharmony_ci    if (table->HasSufficientCapacity(numberOfAddedElements)) {
1014514f5e3Sopenharmony_ci        return table;
1024514f5e3Sopenharmony_ci    }
1034514f5e3Sopenharmony_ci    int newCapacity = ComputeCapacity(table->NumberOfElements() + numberOfAddedElements);
1044514f5e3Sopenharmony_ci    JSHandle<Derived> newTable = Create(thread, newCapacity,
1054514f5e3Sopenharmony_ci        table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
1064514f5e3Sopenharmony_ci    table->Rehash(thread, *newTable);
1074514f5e3Sopenharmony_ci    return newTable;
1084514f5e3Sopenharmony_ci}
1094514f5e3Sopenharmony_ci
1104514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
1114514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::Remove(const JSThread *thread, const JSHandle<Derived> &table,
1124514f5e3Sopenharmony_ci                                                               const JSHandle<JSTaggedValue> &key)
1134514f5e3Sopenharmony_ci{
1144514f5e3Sopenharmony_ci    int entry = table->FindElement(thread, key.GetTaggedValue());
1154514f5e3Sopenharmony_ci    if (entry == -1) {
1164514f5e3Sopenharmony_ci        return table;
1174514f5e3Sopenharmony_ci    }
1184514f5e3Sopenharmony_ci
1194514f5e3Sopenharmony_ci    table->RemoveEntry(thread, entry);
1204514f5e3Sopenharmony_ci    return Shrink(thread, table);
1214514f5e3Sopenharmony_ci}
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_citemplate<typename Derived, typename HashObject>
1244514f5e3Sopenharmony_ciJSHandle<Derived> LinkedHashTable<Derived, HashObject>::Shrink(const JSThread *thread, const JSHandle<Derived> &table,
1254514f5e3Sopenharmony_ci    int additionalCapacity)
1264514f5e3Sopenharmony_ci{
1274514f5e3Sopenharmony_ci    int newCapacity = ComputeCapacityWithShrink(table->Capacity(), table->NumberOfElements() + additionalCapacity);
1284514f5e3Sopenharmony_ci    if (newCapacity == table->Capacity()) {
1294514f5e3Sopenharmony_ci        return table;
1304514f5e3Sopenharmony_ci    }
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci    JSHandle<Derived> newTable = Create(thread, newCapacity,
1334514f5e3Sopenharmony_ci        table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
1344514f5e3Sopenharmony_ci
1354514f5e3Sopenharmony_ci    table->Rehash(thread, *newTable);
1364514f5e3Sopenharmony_ci    return newTable;
1374514f5e3Sopenharmony_ci}
1384514f5e3Sopenharmony_ci
1394514f5e3Sopenharmony_ci// LinkedHashMap
1404514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::Create(const JSThread *thread, int numberOfElements, MemSpaceKind spaceKind)
1414514f5e3Sopenharmony_ci{
1424514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashMap, LinkedHashMapObject>::Create(thread, numberOfElements, spaceKind);
1434514f5e3Sopenharmony_ci}
1444514f5e3Sopenharmony_ci
1454514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::Delete(const JSThread *thread, const JSHandle<LinkedHashMap> &obj,
1464514f5e3Sopenharmony_ci                                              const JSHandle<JSTaggedValue> &key)
1474514f5e3Sopenharmony_ci{
1484514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashMap, LinkedHashMapObject>::Remove(thread, obj, key);
1494514f5e3Sopenharmony_ci}
1504514f5e3Sopenharmony_ci
1514514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::Set(const JSThread *thread, const JSHandle<LinkedHashMap> &obj,
1524514f5e3Sopenharmony_ci    const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)
1534514f5e3Sopenharmony_ci{
1544514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashMap, LinkedHashMapObject>::Insert(thread, obj, key, value);
1554514f5e3Sopenharmony_ci}
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::SetWeakRef(const JSThread *thread, const JSHandle<LinkedHashMap> &obj,
1584514f5e3Sopenharmony_ci    const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)
1594514f5e3Sopenharmony_ci{
1604514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashMap, LinkedHashMapObject>::InsertWeakRef(thread, obj, key, value);
1614514f5e3Sopenharmony_ci}
1624514f5e3Sopenharmony_ci
1634514f5e3Sopenharmony_ciJSTaggedValue LinkedHashMap::Get(const JSThread *thread, JSTaggedValue key) const
1644514f5e3Sopenharmony_ci{
1654514f5e3Sopenharmony_ci    int entry = FindElement(thread, key);
1664514f5e3Sopenharmony_ci    if (entry == -1) {
1674514f5e3Sopenharmony_ci        return JSTaggedValue::Undefined();
1684514f5e3Sopenharmony_ci    }
1694514f5e3Sopenharmony_ci    return GetValue(entry);
1704514f5e3Sopenharmony_ci}
1714514f5e3Sopenharmony_ci
1724514f5e3Sopenharmony_cibool LinkedHashMap::Has(const JSThread *thread, JSTaggedValue key) const
1734514f5e3Sopenharmony_ci{
1744514f5e3Sopenharmony_ci    int entry = FindElement(thread, key);
1754514f5e3Sopenharmony_ci    return entry != -1;
1764514f5e3Sopenharmony_ci}
1774514f5e3Sopenharmony_ci
1784514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::Clear(const JSThread *thread, const JSHandle<LinkedHashMap> &table)
1794514f5e3Sopenharmony_ci{
1804514f5e3Sopenharmony_ci    if (table->Capacity() == LinkedHashMap::MIN_CAPACITY) {
1814514f5e3Sopenharmony_ci        table->FillRangeWithSpecialValue(JSTaggedValue::Hole(), LinkedHashMap::ELEMENTS_START_INDEX,
1824514f5e3Sopenharmony_ci                                         table->GetLength());
1834514f5e3Sopenharmony_ci        table->SetNumberOfDeletedElements(thread, table->NumberOfDeletedElements() + table->NumberOfElements());
1844514f5e3Sopenharmony_ci        table->SetNumberOfElements(thread, 0);
1854514f5e3Sopenharmony_ci        return table;
1864514f5e3Sopenharmony_ci    }
1874514f5e3Sopenharmony_ci    JSHandle<LinkedHashMap> newMap = LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY,
1884514f5e3Sopenharmony_ci        table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
1894514f5e3Sopenharmony_ci    if (table->Capacity() > 0) {
1904514f5e3Sopenharmony_ci        table->SetNextTable(thread, newMap.GetTaggedValue());
1914514f5e3Sopenharmony_ci        table->SetNumberOfDeletedElements(thread, -1);
1924514f5e3Sopenharmony_ci    }
1934514f5e3Sopenharmony_ci    return newMap;
1944514f5e3Sopenharmony_ci}
1954514f5e3Sopenharmony_ci
1964514f5e3Sopenharmony_ciJSHandle<LinkedHashMap> LinkedHashMap::Shrink(const JSThread *thread, const JSHandle<LinkedHashMap> &table,
1974514f5e3Sopenharmony_ci                                              int additionalCapacity)
1984514f5e3Sopenharmony_ci{
1994514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashMap, LinkedHashMapObject>::Shrink(thread, table, additionalCapacity);
2004514f5e3Sopenharmony_ci}
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_ci// LinkedHashSet
2034514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::Create(const JSThread *thread, int numberOfElements, MemSpaceKind spaceKind)
2044514f5e3Sopenharmony_ci{
2054514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashSet, LinkedHashSetObject>::Create(thread, numberOfElements, spaceKind);
2064514f5e3Sopenharmony_ci}
2074514f5e3Sopenharmony_ci
2084514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::Delete(const JSThread *thread, const JSHandle<LinkedHashSet> &obj,
2094514f5e3Sopenharmony_ci                                              const JSHandle<JSTaggedValue> &key)
2104514f5e3Sopenharmony_ci{
2114514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashSet, LinkedHashSetObject>::Remove(thread, obj, key);
2124514f5e3Sopenharmony_ci}
2134514f5e3Sopenharmony_ci
2144514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::Add(const JSThread *thread, const JSHandle<LinkedHashSet> &obj,
2154514f5e3Sopenharmony_ci                                           const JSHandle<JSTaggedValue> &key)
2164514f5e3Sopenharmony_ci{
2174514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashSet, LinkedHashSetObject>::Insert(thread, obj, key, key);
2184514f5e3Sopenharmony_ci}
2194514f5e3Sopenharmony_ci
2204514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::AddWeakRef(const JSThread *thread, const JSHandle<LinkedHashSet> &obj,
2214514f5e3Sopenharmony_ci    const JSHandle<JSTaggedValue> &key)
2224514f5e3Sopenharmony_ci{
2234514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashSet, LinkedHashSetObject>::InsertWeakRef(thread, obj, key, key);
2244514f5e3Sopenharmony_ci}
2254514f5e3Sopenharmony_ci
2264514f5e3Sopenharmony_cibool LinkedHashSet::Has(const JSThread *thread, JSTaggedValue key) const
2274514f5e3Sopenharmony_ci{
2284514f5e3Sopenharmony_ci    int entry = FindElement(thread, key);
2294514f5e3Sopenharmony_ci    return entry != -1;
2304514f5e3Sopenharmony_ci}
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::Clear(const JSThread *thread, const JSHandle<LinkedHashSet> &table)
2334514f5e3Sopenharmony_ci{
2344514f5e3Sopenharmony_ci    if (table->Capacity() == LinkedHashSet::MIN_CAPACITY) {
2354514f5e3Sopenharmony_ci        table->FillRangeWithSpecialValue(JSTaggedValue::Hole(), LinkedHashSet::ELEMENTS_START_INDEX,
2364514f5e3Sopenharmony_ci                                         table->GetLength());
2374514f5e3Sopenharmony_ci        table->SetNumberOfDeletedElements(thread, table->NumberOfDeletedElements() + table->NumberOfElements());
2384514f5e3Sopenharmony_ci        table->SetNumberOfElements(thread, 0);
2394514f5e3Sopenharmony_ci        return table;
2404514f5e3Sopenharmony_ci    }
2414514f5e3Sopenharmony_ci    JSHandle<LinkedHashSet> newSet = LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY,
2424514f5e3Sopenharmony_ci        table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
2434514f5e3Sopenharmony_ci    if (table->Capacity() > 0) {
2444514f5e3Sopenharmony_ci        table->SetNextTable(thread, newSet.GetTaggedValue());
2454514f5e3Sopenharmony_ci        table->SetNumberOfDeletedElements(thread, -1);
2464514f5e3Sopenharmony_ci    }
2474514f5e3Sopenharmony_ci    return newSet;
2484514f5e3Sopenharmony_ci}
2494514f5e3Sopenharmony_ci
2504514f5e3Sopenharmony_ciJSHandle<LinkedHashSet> LinkedHashSet::Shrink(const JSThread *thread, const JSHandle<LinkedHashSet> &table,
2514514f5e3Sopenharmony_ci    int additionalCapacity)
2524514f5e3Sopenharmony_ci{
2534514f5e3Sopenharmony_ci    return LinkedHashTable<LinkedHashSet, LinkedHashSetObject>::Shrink(thread, table, additionalCapacity);
2544514f5e3Sopenharmony_ci}
2554514f5e3Sopenharmony_ci
2564514f5e3Sopenharmony_ciint LinkedHash::Hash(const JSThread *thread, JSTaggedValue key)
2574514f5e3Sopenharmony_ci{
2584514f5e3Sopenharmony_ci    if (key.IsInt()) {
2594514f5e3Sopenharmony_ci        return key.GetInt();
2604514f5e3Sopenharmony_ci    }
2614514f5e3Sopenharmony_ci    if (key.IsSymbol()) {
2624514f5e3Sopenharmony_ci        auto symbolString = JSSymbol::Cast(key.GetTaggedObject());
2634514f5e3Sopenharmony_ci        return symbolString->GetHashField();
2644514f5e3Sopenharmony_ci    }
2654514f5e3Sopenharmony_ci    if (key.IsString()) {
2664514f5e3Sopenharmony_ci        auto keyString = reinterpret_cast<EcmaString *>(key.GetTaggedObject());
2674514f5e3Sopenharmony_ci        return EcmaStringAccessor(keyString).GetHashcode();
2684514f5e3Sopenharmony_ci    }
2694514f5e3Sopenharmony_ci    if (key.IsECMAObject()) {
2704514f5e3Sopenharmony_ci        int32_t hash = ECMAObject::Cast(key.GetTaggedObject())->GetHash();
2714514f5e3Sopenharmony_ci        if (hash == 0) {
2724514f5e3Sopenharmony_ci            hash = base::RandomGenerator::GenerateIdentityHash();
2734514f5e3Sopenharmony_ci            JSHandle<ECMAObject> ecmaObj(thread, key);
2744514f5e3Sopenharmony_ci            ECMAObject::SetHash(thread, hash, ecmaObj);
2754514f5e3Sopenharmony_ci        }
2764514f5e3Sopenharmony_ci        return hash;
2774514f5e3Sopenharmony_ci    }
2784514f5e3Sopenharmony_ci    if (key.IsBigInt()) {
2794514f5e3Sopenharmony_ci        uint32_t keyValue = BigInt::Cast(key.GetTaggedObject())->GetDigit(0);
2804514f5e3Sopenharmony_ci        return GetHash32(reinterpret_cast<uint8_t *>(&keyValue), sizeof(keyValue) / sizeof(uint8_t));
2814514f5e3Sopenharmony_ci    }
2824514f5e3Sopenharmony_ci    // Int, Double, Special and HeapObject(except symbol and string)
2834514f5e3Sopenharmony_ci    if (key.IsDouble()) {
2844514f5e3Sopenharmony_ci        key = JSTaggedValue::TryCastDoubleToInt32(key.GetDouble());
2854514f5e3Sopenharmony_ci        if (key.IsInt()) {
2864514f5e3Sopenharmony_ci            return key.GetInt();
2874514f5e3Sopenharmony_ci        }
2884514f5e3Sopenharmony_ci    }
2894514f5e3Sopenharmony_ci    uint64_t keyValue = key.GetRawData();
2904514f5e3Sopenharmony_ci    return GetHash32(reinterpret_cast<uint8_t *>(&keyValue), sizeof(keyValue) / sizeof(uint8_t));
2914514f5e3Sopenharmony_ci}
2924514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
293