1 /* 2 * Copyright (c) 2023 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 16 #ifndef ECMASCRIPT_JS_TAGGED_VALUE_INTERNALS_H 17 #define ECMASCRIPT_JS_TAGGED_VALUE_INTERNALS_H 18 19 #include "ecmascript/base/bit_helper.h" 20 21 namespace panda::ecmascript { 22 23 using JSTaggedType = uint64_t; 24 25 // Every double with all of its exponent bits set and its highest mantissa bit set is a quiet NaN. 26 // That leaves 51 bits unaccounted for. We’ll avoid one of those so that we don’t step on Intel’s 27 // “QNaN Floating-Point Indefinite” value, leaving us 50 bits. Those remaining bits can be anything. 28 // so we use a special quietNaN as TaggedInt tag(highest 16bits as 0xFFFF), and need to encode double 29 // to the value will begin with a 16-bit pattern within the range 0x0001..0xFFFE. 30 31 // Nan-boxing pointer is used and the first four bytes are used as tag: 32 // Object: [0x0000] [48 bit direct pointer] 33 // WeakRef: [0x0000] [47 bits direct pointer] | 1 34 // / [0x0001] [48 bit any value] 35 // TaggedDouble: ...... 36 // \ [0xFFFE] [48 bit any value] 37 // TaggedInt: [0xFFFF] [0x0000] [32 bit signed integer] 38 // 39 // There are some special markers of Object: 40 // False: [56 bits 0] | 0x06 // 0110 41 // True: [56 bits 0] | 0x07 // 0111 42 // Undefined: [56 bits 0] | 0x02 // 0010 43 // Null: [56 bits 0] | 0x03 // 0011 44 // Hole: [56 bits 0] | 0x05 // 0101 45 // Optimized: [56 bits 0] | 0x0C // 1100 46 47 class JSTaggedValueInternals { 48 public: 49 static constexpr size_t BIT_PER_BYTE = 8; 50 static constexpr size_t TAG_BITS_SIZE = 16; // 16 means bit numbers of 0xFFFF 51 static constexpr size_t TAG_BITS_SHIFT = base::BitNumbers<JSTaggedType>() - TAG_BITS_SIZE; 52 static_assert((TAG_BITS_SHIFT + TAG_BITS_SIZE) == sizeof(JSTaggedType) * BIT_PER_BYTE, "Insufficient bits!"); 53 static constexpr JSTaggedType TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; 54 // int tag 55 static constexpr JSTaggedType TAG_INT = TAG_MARK; 56 static constexpr JSTaggedType TAG_INT32_INC_MAX = INT32_MAX + 1ULL; 57 static constexpr JSTaggedType TAG_INT32_DEC_MIN = INT32_MIN - 1ULL; 58 // object tag 59 static constexpr JSTaggedType TAG_OBJECT = 0x0000ULL << TAG_BITS_SHIFT; 60 // weak object tag 61 static constexpr JSTaggedType TAG_WEAK = TAG_OBJECT | 0x01ULL; 62 // special tag 63 static constexpr JSTaggedType TAG_NULL = 0x01ULL; 64 static constexpr JSTaggedType TAG_SPECIAL = 0x02ULL; 65 static constexpr JSTaggedType TAG_BOOLEAN = 0x04ULL; 66 static constexpr JSTaggedType TAG_EXCEPTION = 0x08ULL; 67 static constexpr JSTaggedType TAG_OPTIMIZED_OUT = 0x12ULL; 68 // tag mask 69 static constexpr JSTaggedType TAG_SPECIAL_MASK = TAG_MARK | TAG_SPECIAL; 70 static constexpr JSTaggedType TAG_BOOLEAN_MASK = TAG_SPECIAL | TAG_BOOLEAN; 71 static constexpr JSTaggedType TAG_HEAPOBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; 72 static constexpr JSTaggedType TAG_WEAK_MASK = TAG_HEAPOBJECT_MASK | TAG_WEAK; 73 // special value 74 static constexpr JSTaggedType VALUE_HOLE = 0x05ULL; 75 static constexpr JSTaggedType VALUE_NULL = TAG_OBJECT | TAG_SPECIAL | TAG_NULL; 76 static constexpr JSTaggedType VALUE_FALSE = TAG_BOOLEAN_MASK | static_cast<JSTaggedType>(false); 77 static constexpr JSTaggedType VALUE_TRUE = TAG_BOOLEAN_MASK | static_cast<JSTaggedType>(true); 78 static constexpr JSTaggedType VALUE_UNDEFINED = TAG_SPECIAL; 79 static constexpr JSTaggedType VALUE_EXCEPTION = TAG_SPECIAL | TAG_EXCEPTION; 80 static constexpr JSTaggedType VALUE_ZERO = TAG_INT | 0x00ULL; 81 static constexpr JSTaggedType VALUE_OPTIMIZED_OUT = TAG_SPECIAL | TAG_OPTIMIZED_OUT; 82 83 static constexpr size_t INT_SIGN_BIT_OFFSET = 31; 84 static constexpr size_t DOUBLE_ENCODE_OFFSET_BIT = 48; 85 static constexpr JSTaggedType DOUBLE_ENCODE_OFFSET = 1ULL << DOUBLE_ENCODE_OFFSET_BIT; 86 // Tagged +0.0 = IEEE754 representation of +0.0 + offset 87 static constexpr JSTaggedType VALUE_POSITIVE_ZERO = 0x0000'0000'0000'0000uLL + DOUBLE_ENCODE_OFFSET; 88 // Tagged -0.0 = IEEE754 representation of -0.0 + offset 89 static constexpr JSTaggedType VALUE_NEGATIVE_ZERO = 0x8000'0000'0000'0000uLL + DOUBLE_ENCODE_OFFSET; 90 }; 91 } // namespace panda::ecmascript 92 #endif // ECMASCRIPT_JS_TAGGED_VALUE_INTERNALS_H 93