14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 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#ifndef ECMASCRIPT_ELEMENTS_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_ELEMENTS_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/global_env_constants.h" 204514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h" 214514f5e3Sopenharmony_ci#include "ecmascript/mem/c_containers.h" 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace panda::ecmascript { 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ci#define ELEMENTS_KIND_INIT_HCLASS_LIST(V) \ 264514f5e3Sopenharmony_ci V(NONE) \ 274514f5e3Sopenharmony_ci V(HOLE) \ 284514f5e3Sopenharmony_ci V(INT) \ 294514f5e3Sopenharmony_ci V(NUMBER) \ 304514f5e3Sopenharmony_ci V(STRING) \ 314514f5e3Sopenharmony_ci V(OBJECT) \ 324514f5e3Sopenharmony_ci V(TAGGED) \ 334514f5e3Sopenharmony_ci V(HOLE_INT) \ 344514f5e3Sopenharmony_ci V(HOLE_NUMBER) \ 354514f5e3Sopenharmony_ci V(HOLE_STRING) \ 364514f5e3Sopenharmony_ci V(HOLE_OBJECT) \ 374514f5e3Sopenharmony_ci V(HOLE_TAGGED) 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_cienum class ElementsKind : uint8_t { 404514f5e3Sopenharmony_ci NONE = 0x00UL, 414514f5e3Sopenharmony_ci HOLE = 0x01UL, 424514f5e3Sopenharmony_ci INT = 0x1UL << 1, // 2 434514f5e3Sopenharmony_ci NUMBER = (0x1UL << 2) | INT, // 6 444514f5e3Sopenharmony_ci STRING = 0x1UL << 3, // 8 454514f5e3Sopenharmony_ci OBJECT = 0x1UL << 4, // 16 464514f5e3Sopenharmony_ci TAGGED = 0x1EUL, // 30 474514f5e3Sopenharmony_ci HOLE_INT = HOLE | INT, 484514f5e3Sopenharmony_ci HOLE_NUMBER = HOLE | NUMBER, 494514f5e3Sopenharmony_ci HOLE_STRING = HOLE | STRING, 504514f5e3Sopenharmony_ci HOLE_OBJECT = HOLE | OBJECT, 514514f5e3Sopenharmony_ci HOLE_TAGGED = HOLE | TAGGED, 524514f5e3Sopenharmony_ci GENERIC = HOLE_TAGGED, 534514f5e3Sopenharmony_ci DICTIONARY = HOLE_TAGGED, 544514f5e3Sopenharmony_ci}; 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ciclass PUBLIC_API Elements { 574514f5e3Sopenharmony_cipublic: 584514f5e3Sopenharmony_ci static CMap<ElementsKind, std::pair<ConstantIndex, ConstantIndex>> InitializeHClassMap(); 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_ci static std::string GetString(ElementsKind kind); 614514f5e3Sopenharmony_ci static bool IsInt(ElementsKind kind); 624514f5e3Sopenharmony_ci static bool IsNumber(ElementsKind kind); 634514f5e3Sopenharmony_ci static bool IsTagged(ElementsKind kind); 644514f5e3Sopenharmony_ci static bool IsObject(ElementsKind kind); 654514f5e3Sopenharmony_ci static bool IsHole(ElementsKind kind); 664514f5e3Sopenharmony_ci static bool IsGeneric(ElementsKind kind) 674514f5e3Sopenharmony_ci { 684514f5e3Sopenharmony_ci return kind == ElementsKind::GENERIC; 694514f5e3Sopenharmony_ci } 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ci static bool IsNone(ElementsKind kind) 724514f5e3Sopenharmony_ci { 734514f5e3Sopenharmony_ci return kind == ElementsKind::NONE; 744514f5e3Sopenharmony_ci } 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_ci static bool IsComplex(ElementsKind kind) 774514f5e3Sopenharmony_ci { 784514f5e3Sopenharmony_ci return IsNumber(kind) || IsTagged(kind); 794514f5e3Sopenharmony_ci } 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ci static bool IsInNumbers(ElementsKind kind) 824514f5e3Sopenharmony_ci { 834514f5e3Sopenharmony_ci return (static_cast<uint32_t>(kind) > static_cast<uint32_t>(ElementsKind::HOLE) && 844514f5e3Sopenharmony_ci static_cast<uint32_t>(kind) < static_cast<uint32_t>(ElementsKind::STRING)); 854514f5e3Sopenharmony_ci } 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_ci static bool IsHoleInt(ElementsKind kind) 884514f5e3Sopenharmony_ci { 894514f5e3Sopenharmony_ci return kind == ElementsKind::HOLE_INT; 904514f5e3Sopenharmony_ci } 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_ci static bool IsHoleNumber(ElementsKind kind) 934514f5e3Sopenharmony_ci { 944514f5e3Sopenharmony_ci return kind == ElementsKind::HOLE_NUMBER; 954514f5e3Sopenharmony_ci } 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ci static ConstantIndex GetGlobalContantIndexByKind(ElementsKind kind); 984514f5e3Sopenharmony_ci static ElementsKind MergeElementsKind(ElementsKind curKind, ElementsKind newKind); 994514f5e3Sopenharmony_ci static ElementsKind FixElementsKind(ElementsKind oldKind); 1004514f5e3Sopenharmony_ci static ElementsKind ToElementsKind(JSTaggedValue value, ElementsKind kind); 1014514f5e3Sopenharmony_ci static void MigrateArrayWithKind(const JSThread *thread, const JSHandle<JSObject> &object, 1024514f5e3Sopenharmony_ci const ElementsKind oldKind, const ElementsKind newKind); 1034514f5e3Sopenharmony_ciprivate: 1044514f5e3Sopenharmony_ci static JSTaggedValue MigrateFromRawValueToHeapValue(const JSThread *thread, const JSHandle<JSObject> object, 1054514f5e3Sopenharmony_ci bool needCOW, bool isIntKind); 1064514f5e3Sopenharmony_ci static void HandleIntKindMigration(const JSThread *thread, const JSHandle<JSObject> &object, 1074514f5e3Sopenharmony_ci const ElementsKind newKind, bool needCOW); 1084514f5e3Sopenharmony_ci static bool IsNumberKind(const ElementsKind kind); 1094514f5e3Sopenharmony_ci static bool IsStringOrNoneOrHole(const ElementsKind kind); 1104514f5e3Sopenharmony_ci static void HandleNumberKindMigration(const JSThread *thread, 1114514f5e3Sopenharmony_ci const JSHandle<JSObject> &object, 1124514f5e3Sopenharmony_ci const ElementsKind newKind, bool needCOW); 1134514f5e3Sopenharmony_ci static void HandleOtherKindMigration(const JSThread *thread, const JSHandle<JSObject> &object, 1144514f5e3Sopenharmony_ci const ElementsKind newKind, bool needCOW); 1154514f5e3Sopenharmony_ci static JSTaggedValue MigrateFromHeapValueToRawValue(const JSThread *thread, const JSHandle<JSObject> object, 1164514f5e3Sopenharmony_ci bool needCOW, bool isIntKind); 1174514f5e3Sopenharmony_ci static void MigrateFromHoleIntToHoleNumber(const JSThread *thread, const JSHandle<JSObject> object); 1184514f5e3Sopenharmony_ci static void MigrateFromHoleNumberToHoleInt(const JSThread *thread, const JSHandle<JSObject> object); 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_ci}; 1214514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1224514f5e3Sopenharmony_ci#endif // ECMASCRIPT_ELEMENTS_H 123