CacheIRReader.h (5547B)
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 jit_CacheIRReader_h 8 #define jit_CacheIRReader_h 9 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Attributes.h" 12 #include "mozilla/Maybe.h" 13 14 #include <stdint.h> 15 #include "NamespaceImports.h" 16 17 #include "jit/CacheIR.h" 18 #include "jit/CacheIROpsGenerated.h" 19 #include "jit/CacheIRWriter.h" 20 #include "jit/CompactBuffer.h" 21 #include "js/ScalarType.h" 22 #include "js/Value.h" 23 #include "vm/TypeofEqOperand.h" // TypeofEqOperand 24 #include "wasm/WasmValType.h" 25 26 enum class JSOp : uint8_t; 27 28 namespace js { 29 30 enum class UnaryMathFunction : uint8_t; 31 32 namespace gc { 33 enum class AllocKind : uint8_t; 34 } 35 36 namespace jit { 37 38 class CacheIRStubInfo; 39 40 // Helper class for reading CacheIR bytecode. 41 class MOZ_RAII CacheIRReader { 42 CompactBufferReader buffer_; 43 #ifdef DEBUG 44 mozilla::Maybe<CacheOp> lastOp_; 45 #endif 46 47 CacheIRReader(const CacheIRReader&) = delete; 48 CacheIRReader& operator=(const CacheIRReader&) = delete; 49 50 public: 51 CacheIRReader(const uint8_t* start, const uint8_t* end) 52 : buffer_(start, end) {} 53 explicit CacheIRReader(const CacheIRWriter& writer) 54 : CacheIRReader(writer.codeStart(), writer.codeEnd()) {} 55 explicit CacheIRReader(const CacheIRStubInfo* stubInfo); 56 57 bool more() const { return buffer_.more(); } 58 59 CacheOp readOp() { 60 CacheOp op = CacheOp(buffer_.readFixedUint16_t()); 61 #ifdef DEBUG 62 lastOp_ = mozilla::Some(op); 63 #endif 64 return op; 65 } 66 CacheOp peekOp() { return CacheOp(buffer_.peekFixedUint16_t()); } 67 68 // Skip data not currently used. 69 void skip() { buffer_.readByte(); } 70 void skip(uint32_t skipLength) { 71 if (skipLength > 0) { 72 buffer_.seek(buffer_.currentPosition(), skipLength); 73 } 74 } 75 76 ValOperandId valOperandId() { return ValOperandId(buffer_.readByte()); } 77 ValueTagOperandId valueTagOperandId() { 78 return ValueTagOperandId(buffer_.readByte()); 79 } 80 81 IntPtrOperandId intPtrOperandId() { 82 return IntPtrOperandId(buffer_.readByte()); 83 } 84 85 ObjOperandId objOperandId() { return ObjOperandId(buffer_.readByte()); } 86 NumberOperandId numberOperandId() { 87 return NumberOperandId(buffer_.readByte()); 88 } 89 StringOperandId stringOperandId() { 90 return StringOperandId(buffer_.readByte()); 91 } 92 93 SymbolOperandId symbolOperandId() { 94 return SymbolOperandId(buffer_.readByte()); 95 } 96 97 BigIntOperandId bigIntOperandId() { 98 return BigIntOperandId(buffer_.readByte()); 99 } 100 101 BooleanOperandId booleanOperandId() { 102 return BooleanOperandId(buffer_.readByte()); 103 } 104 105 Int32OperandId int32OperandId() { return Int32OperandId(buffer_.readByte()); } 106 107 uint32_t rawOperandId() { return buffer_.readByte(); } 108 109 uint32_t stubOffset() { return buffer_.readByte() * sizeof(uintptr_t); } 110 GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); } 111 ArrayBufferViewKind arrayBufferViewKind() { 112 return ArrayBufferViewKind(buffer_.readByte()); 113 } 114 ValueType valueType() { return ValueType(buffer_.readByte()); } 115 wasm::ValType::Kind wasmValType() { 116 return wasm::ValType::Kind(buffer_.readByte()); 117 } 118 gc::AllocKind allocKind() { return gc::AllocKind(buffer_.readByte()); } 119 CompletionKind completionKind() { return CompletionKind(buffer_.readByte()); } 120 RealmFuses::FuseIndex realmFuseIndex() { 121 return RealmFuses::FuseIndex(buffer_.readByte()); 122 } 123 RuntimeFuses::FuseIndex runtimeFuseIndex() { 124 return RuntimeFuses::FuseIndex(buffer_.readByte()); 125 } 126 127 Scalar::Type scalarType() { return Scalar::Type(buffer_.readByte()); } 128 JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); } 129 JSOp jsop() { return JSOp(buffer_.readByte()); } 130 TypeofEqOperand typeofEqOperand() { 131 return TypeofEqOperand::fromRawValue(buffer_.readByte()); 132 } 133 int32_t int32Immediate() { return int32_t(buffer_.readFixedUint32_t()); } 134 uint32_t uint32Immediate() { return buffer_.readFixedUint32_t(); } 135 void* pointer() { return buffer_.readRawPointer(); } 136 137 UnaryMathFunction unaryMathFunction() { 138 return UnaryMathFunction(buffer_.readByte()); 139 } 140 141 CallFlags callFlags() { 142 // See CacheIRWriter::writeCallFlagsImm() 143 uint8_t encoded = buffer_.readByte(); 144 CallFlags::ArgFormat format = 145 CallFlags::ArgFormat(encoded & CallFlags::ArgFormatMask); 146 bool isConstructing = encoded & CallFlags::IsConstructing; 147 bool isSameRealm = encoded & CallFlags::IsSameRealm; 148 bool needsUninitializedThis = encoded & CallFlags::NeedsUninitializedThis; 149 MOZ_ASSERT_IF(needsUninitializedThis, isConstructing); 150 151 // FunCall and FunApply can't be constructors. 152 MOZ_ASSERT_IF(format == CallFlags::FunCall, !isConstructing); 153 MOZ_ASSERT_IF(format == CallFlags::FunApplyArgsObj, !isConstructing); 154 MOZ_ASSERT_IF(format == CallFlags::FunApplyArray, !isConstructing); 155 MOZ_ASSERT_IF(format == CallFlags::FunApplyNullUndefined, !isConstructing); 156 157 return CallFlags(format, isConstructing, isSameRealm, 158 needsUninitializedThis); 159 } 160 161 uint8_t readByte() { return buffer_.readByte(); } 162 bool readBool() { 163 uint8_t b = buffer_.readByte(); 164 MOZ_ASSERT(b <= 1); 165 return bool(b); 166 } 167 168 const uint8_t* currentPosition() const { return buffer_.currentPosition(); } 169 170 CACHE_IR_READER_GENERATED 171 }; 172 173 } // namespace jit 174 } // namespace js 175 176 #endif /* jit_CacheIRReader_h */