ConstantCompareOperand.h (2846B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef vm_ConstantCompareOperand_h 8 #define vm_ConstantCompareOperand_h 9 10 #include <stdint.h> 11 12 #include "js/Value.h" 13 14 namespace js { 15 16 /* 17 * Simple struct for encoding comparison operations with parse-time constant 18 * values, presently used with the |StrictConstantEq| and |StrictConstantNe| 19 * opcodes. 20 * 21 * The operand encodes the type of the constant and its payload. The type is 22 * encoded in the high-byte and the payload in the low-byte of a 16-bit word. 23 * 24 * TODO (Bug 1958722): Investigate if larger payloads can be supported in the 25 * empty bits of the type. 26 */ 27 struct ConstantCompareOperand { 28 public: 29 enum class EncodedType : uint8_t { 30 Int32 = JSVAL_TYPE_INT32, 31 Boolean = JSVAL_TYPE_BOOLEAN, 32 Null = JSVAL_TYPE_NULL, 33 Undefined = JSVAL_TYPE_UNDEFINED, 34 }; 35 static constexpr uint16_t OFFSET_OF_TYPE = 36 sizeof(jsbytecode) + sizeof(JSValueType); 37 static constexpr uint16_t OFFSET_OF_VALUE = sizeof(jsbytecode); 38 39 private: 40 uint16_t value_; 41 42 static constexpr uint8_t SHIFT_TYPE = 8; 43 static constexpr uint16_t MASK_TYPE = 0xFF00; 44 static constexpr uint16_t MASK_VALUE = 0x00FF; 45 46 static uint16_t encodeType(EncodedType type) { 47 return static_cast<uint16_t>(type) << SHIFT_TYPE; 48 } 49 50 explicit ConstantCompareOperand(uint16_t value) : value_(value) {} 51 52 public: 53 explicit ConstantCompareOperand(int8_t value) 54 : value_(encodeType(EncodedType::Int32) | static_cast<uint8_t>(value)) { 55 MOZ_ASSERT(this->toInt32() == value); 56 } 57 explicit ConstantCompareOperand(bool value) 58 : value_(encodeType(EncodedType::Boolean) | value) { 59 MOZ_ASSERT(this->toBoolean() == value); 60 } 61 explicit ConstantCompareOperand(EncodedType type) : value_(encodeType(type)) { 62 MOZ_ASSERT(type == EncodedType::Undefined || type == EncodedType::Null); 63 MOZ_ASSERT(type == this->type()); 64 } 65 66 static ConstantCompareOperand fromRawValue(uint16_t value) { 67 return ConstantCompareOperand(value); 68 } 69 70 static bool CanEncodeInt32ValueAsOperand(int32_t value) { 71 return value >= INT8_MIN && value <= INT8_MAX; 72 } 73 74 EncodedType type() const { 75 return static_cast<EncodedType>((value_ & MASK_TYPE) >> SHIFT_TYPE); 76 } 77 78 int32_t toInt32() const { 79 MOZ_ASSERT(type() == EncodedType::Int32); 80 return static_cast<int8_t>(value_ & MASK_VALUE); 81 } 82 83 bool toBoolean() const { 84 MOZ_ASSERT(type() == EncodedType::Boolean); 85 return bool(value_ & MASK_VALUE); 86 } 87 88 uint16_t rawValue() const { return value_; } 89 }; 90 91 } // namespace js 92 93 #endif /* vm_ConstantCompareOperand_h */