2023-08-02 01:56:06 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef ECMASCRIPT_ELEMENTS_H
|
|
|
|
#define ECMASCRIPT_ELEMENTS_H
|
|
|
|
|
|
|
|
#include "ecmascript/global_env_constants.h"
|
|
|
|
#include "ecmascript/js_tagged_value.h"
|
|
|
|
#include "ecmascript/mem/c_containers.h"
|
|
|
|
|
|
|
|
namespace panda::ecmascript {
|
2024-07-20 08:21:36 +00:00
|
|
|
|
|
|
|
#define ELEMENTS_KIND_INIT_HCLASS_LIST(V) \
|
|
|
|
V(NONE) \
|
|
|
|
V(HOLE) \
|
|
|
|
V(INT) \
|
|
|
|
V(NUMBER) \
|
|
|
|
V(STRING) \
|
|
|
|
V(OBJECT) \
|
|
|
|
V(TAGGED) \
|
|
|
|
V(HOLE_INT) \
|
|
|
|
V(HOLE_NUMBER) \
|
|
|
|
V(HOLE_STRING) \
|
|
|
|
V(HOLE_OBJECT) \
|
|
|
|
V(HOLE_TAGGED)
|
|
|
|
|
2023-08-02 01:56:06 +00:00
|
|
|
enum class ElementsKind : uint8_t {
|
|
|
|
NONE = 0x00UL,
|
|
|
|
HOLE = 0x01UL,
|
|
|
|
INT = 0x1UL << 1, // 2
|
2023-08-21 12:11:01 +00:00
|
|
|
NUMBER = (0x1UL << 2) | INT, // 6
|
2023-08-02 01:56:06 +00:00
|
|
|
STRING = 0x1UL << 3, // 8
|
|
|
|
OBJECT = 0x1UL << 4, // 16
|
|
|
|
TAGGED = 0x1EUL, // 30
|
|
|
|
HOLE_INT = HOLE | INT,
|
|
|
|
HOLE_NUMBER = HOLE | NUMBER,
|
|
|
|
HOLE_STRING = HOLE | STRING,
|
|
|
|
HOLE_OBJECT = HOLE | OBJECT,
|
|
|
|
HOLE_TAGGED = HOLE | TAGGED,
|
|
|
|
GENERIC = HOLE_TAGGED,
|
2023-12-18 07:57:47 +00:00
|
|
|
DICTIONARY = HOLE_TAGGED,
|
2023-08-02 01:56:06 +00:00
|
|
|
};
|
|
|
|
|
2024-01-10 01:48:32 +00:00
|
|
|
class PUBLIC_API Elements {
|
2023-08-02 01:56:06 +00:00
|
|
|
public:
|
2024-07-20 08:21:36 +00:00
|
|
|
static CMap<ElementsKind, std::pair<ConstantIndex, ConstantIndex>> InitializeHClassMap();
|
2023-08-02 01:56:06 +00:00
|
|
|
|
|
|
|
static std::string GetString(ElementsKind kind);
|
2023-08-07 11:29:14 +00:00
|
|
|
static bool IsInt(ElementsKind kind);
|
2023-08-21 12:11:01 +00:00
|
|
|
static bool IsNumber(ElementsKind kind);
|
|
|
|
static bool IsTagged(ElementsKind kind);
|
2023-08-10 21:07:42 +00:00
|
|
|
static bool IsObject(ElementsKind kind);
|
2023-08-02 01:56:06 +00:00
|
|
|
static bool IsHole(ElementsKind kind);
|
|
|
|
static bool IsGeneric(ElementsKind kind)
|
|
|
|
{
|
|
|
|
return kind == ElementsKind::GENERIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsNone(ElementsKind kind)
|
|
|
|
{
|
|
|
|
return kind == ElementsKind::NONE;
|
|
|
|
}
|
|
|
|
|
2023-08-21 12:11:01 +00:00
|
|
|
static bool IsComplex(ElementsKind kind)
|
|
|
|
{
|
|
|
|
return IsNumber(kind) || IsTagged(kind);
|
|
|
|
}
|
|
|
|
|
2023-12-18 07:57:47 +00:00
|
|
|
static bool IsInNumbers(ElementsKind kind)
|
|
|
|
{
|
2024-02-19 06:55:36 +00:00
|
|
|
return (static_cast<uint32_t>(kind) > static_cast<uint32_t>(ElementsKind::HOLE) &&
|
2023-12-18 07:57:47 +00:00
|
|
|
static_cast<uint32_t>(kind) < static_cast<uint32_t>(ElementsKind::STRING));
|
|
|
|
}
|
|
|
|
|
2024-02-19 06:55:36 +00:00
|
|
|
static bool IsHoleInt(ElementsKind kind)
|
|
|
|
{
|
|
|
|
return kind == ElementsKind::HOLE_INT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsHoleNumber(ElementsKind kind)
|
|
|
|
{
|
|
|
|
return kind == ElementsKind::HOLE_NUMBER;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ConstantIndex GetGlobalContantIndexByKind(ElementsKind kind);
|
2023-08-02 01:56:06 +00:00
|
|
|
static ElementsKind MergeElementsKind(ElementsKind curKind, ElementsKind newKind);
|
|
|
|
static ElementsKind FixElementsKind(ElementsKind oldKind);
|
|
|
|
static ElementsKind ToElementsKind(JSTaggedValue value, ElementsKind kind);
|
2023-12-18 07:57:47 +00:00
|
|
|
static void MigrateArrayWithKind(const JSThread *thread, const JSHandle<JSObject> &object,
|
|
|
|
const ElementsKind oldKind, const ElementsKind newKind);
|
2024-02-19 06:55:36 +00:00
|
|
|
private:
|
|
|
|
static JSTaggedValue MigrateFromRawValueToHeapValue(const JSThread *thread, const JSHandle<JSObject> object,
|
|
|
|
bool needCOW, bool isIntKind);
|
2024-05-22 03:11:31 +00:00
|
|
|
static void HandleIntKindMigration(const JSThread *thread, const JSHandle<JSObject> &object,
|
|
|
|
const ElementsKind newKind, bool needCOW);
|
|
|
|
static bool IsNumberKind(const ElementsKind kind);
|
|
|
|
static bool IsStringOrNoneOrHole(const ElementsKind kind);
|
|
|
|
static void HandleNumberKindMigration(const JSThread *thread,
|
|
|
|
const JSHandle<JSObject> &object,
|
|
|
|
const ElementsKind newKind, bool needCOW);
|
|
|
|
static void HandleOtherKindMigration(const JSThread *thread, const JSHandle<JSObject> &object,
|
|
|
|
const ElementsKind newKind, bool needCOW);
|
2024-02-19 06:55:36 +00:00
|
|
|
static JSTaggedValue MigrateFromHeapValueToRawValue(const JSThread *thread, const JSHandle<JSObject> object,
|
|
|
|
bool needCOW, bool isIntKind);
|
|
|
|
static void MigrateFromHoleIntToHoleNumber(const JSThread *thread, const JSHandle<JSObject> object);
|
|
|
|
static void MigrateFromHoleNumberToHoleInt(const JSThread *thread, const JSHandle<JSObject> object);
|
|
|
|
|
2023-08-02 01:56:06 +00:00
|
|
|
};
|
|
|
|
} // namespace panda::ecmascript
|
|
|
|
#endif // ECMASCRIPT_ELEMENTS_H
|