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_SERIALIZER_BASE_DESERIALIZER_H 17 #define ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H 18 19 #include "ecmascript/js_serializer.h" 20 #include "ecmascript/serializer/serialize_data.h" 21 22 namespace panda::ecmascript { 23 class Heap; 24 class JSThread; 25 struct NewConstPoolInfo { 26 JSPandaFile *jsPandaFile_ {nullptr}; 27 panda_file::File::EntityId methodId_; 28 uintptr_t objAddr_ {0U}; 29 size_t offset_ {0U}; 30 NewConstPoolInfoNewConstPoolInfo31 NewConstPoolInfo(JSPandaFile *jsPandaFile, panda_file::File::EntityId methodId) 32 : jsPandaFile_(jsPandaFile), methodId_(methodId) {} 33 GetObjAddrNewConstPoolInfo34 uintptr_t GetObjAddr() const 35 { 36 return objAddr_; 37 } 38 GetFieldOffsetNewConstPoolInfo39 size_t GetFieldOffset() const 40 { 41 return offset_; 42 } 43 GetSlotNewConstPoolInfo44 ObjectSlot GetSlot() const 45 { 46 return ObjectSlot(objAddr_ + offset_); 47 } 48 }; 49 50 struct NativeBindingInfo { 51 AttachFunc af_ {nullptr}; 52 void *bufferPointer_ {nullptr}; 53 void *hint_ = {nullptr}; 54 void *attachData_ = {nullptr}; 55 uintptr_t objAddr_ {0U}; 56 size_t offset_ {0U}; 57 bool root_ {false}; 58 NativeBindingInfoNativeBindingInfo59 NativeBindingInfo(AttachFunc af, void *bufferPointer, void *hint, void *attachData, 60 uintptr_t objAddr, size_t offset, bool root) : af_(af), bufferPointer_(bufferPointer), 61 hint_(hint), attachData_(attachData), objAddr_(objAddr), offset_(offset), root_(root) {} 62 GetObjAddrNativeBindingInfo63 uintptr_t GetObjAddr() const 64 { 65 return objAddr_; 66 } 67 GetFieldOffsetNativeBindingInfo68 size_t GetFieldOffset() const 69 { 70 return offset_; 71 } 72 GetSlotNativeBindingInfo73 ObjectSlot GetSlot() const 74 { 75 return ObjectSlot(objAddr_ + offset_); 76 } 77 }; 78 79 struct JSErrorInfo { 80 uint8_t errorType_ {0}; 81 JSTaggedValue errorMsg_; 82 uintptr_t objAddr_ {0U}; 83 size_t offset_ {0U}; 84 bool root_ {false}; 85 JSErrorInfoJSErrorInfo86 JSErrorInfo(uint8_t errorType, JSTaggedValue errorMsg, uintptr_t objAddr, size_t offset, bool root) 87 : errorType_(errorType), errorMsg_(errorMsg), objAddr_(objAddr), offset_(offset), root_(root) {} 88 GetObjAddrJSErrorInfo89 uintptr_t GetObjAddr() const 90 { 91 return objAddr_; 92 } 93 GetFieldOffsetJSErrorInfo94 size_t GetFieldOffset() const 95 { 96 return offset_; 97 } 98 GetSlotJSErrorInfo99 ObjectSlot GetSlot() const 100 { 101 return ObjectSlot(objAddr_ + offset_); 102 } 103 }; 104 105 class BaseDeserializer { 106 public: 107 explicit BaseDeserializer(JSThread *thread, SerializeData *data, void *hint = nullptr) thread_(thread)108 : thread_(thread), heap_(const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())), data_(data), engine_(hint) {} ~BaseDeserializer()109 ~BaseDeserializer() 110 { 111 data_->ResetPosition(); 112 objectVector_.clear(); 113 regionVector_.clear(); 114 } 115 116 NO_COPY_SEMANTIC(BaseDeserializer); 117 NO_MOVE_SEMANTIC(BaseDeserializer); 118 119 JSHandle<JSTaggedValue> ReadValue(); 120 121 private: 122 JSHandle<JSTaggedValue> DeserializeJSTaggedValue(); 123 uintptr_t DeserializeTaggedObject(SerializedObjectSpace space); 124 void DeserializeConstPool(NewConstPoolInfo *info); 125 void DeserializeNativeBindingObject(NativeBindingInfo *info); 126 void DeserializeJSError(JSErrorInfo *info); 127 uintptr_t RelocateObjectAddr(SerializedObjectSpace space, size_t objSize); 128 JSTaggedType RelocateObjectProtoAddr(uint8_t objectType); 129 void DeserializeObjectField(uintptr_t start, uintptr_t end); 130 size_t ReadSingleEncodeData(uint8_t encodeFlag, uintptr_t objAddr, size_t fieldOffset, bool isRoot = false); 131 void HandleNewObjectEncodeFlag(SerializedObjectSpace space, uintptr_t objAddr, size_t fieldOffset, bool isRoot); 132 void HandleMethodEncodeFlag(); 133 134 void TransferArrayBufferAttach(uintptr_t objAddr); 135 void ResetNativePointerBuffer(uintptr_t objAddr, void *bufferPointer); 136 void ResetMethodConstantPool(uintptr_t objAddr, ConstantPool *constpool); 137 138 void AllocateToDifferentSpaces(); 139 void AllocateMultiRegion(SparseSpace *space, size_t spaceObjSize, size_t ®ionIndex); 140 void AllocateToOldSpace(size_t oldSpaceSize); 141 void AllocateToNonMovableSpace(size_t nonMovableSpaceSize); 142 void AllocateToMachineCodeSpace(size_t machineCodeSpaceSize); 143 GetAndResetWeak()144 bool GetAndResetWeak() 145 { 146 bool isWeak = isWeak_; 147 if (isWeak_) { 148 isWeak_ = false; 149 } 150 return isWeak; 151 } 152 GetAndResetTransferBuffer()153 bool GetAndResetTransferBuffer() 154 { 155 bool isTransferArrayBuffer = isTransferArrayBuffer_; 156 if (isTransferArrayBuffer_) { 157 isTransferArrayBuffer_ = false; 158 } 159 return isTransferArrayBuffer; 160 } 161 GetAndResetNeedNewConstPool()162 bool GetAndResetNeedNewConstPool() 163 { 164 bool needNewConstPool = needNewConstPool_; 165 if (needNewConstPool_) { 166 needNewConstPool_ = false; 167 } 168 return needNewConstPool; 169 } 170 GetAndResetIsErrorMsg()171 bool GetAndResetIsErrorMsg() 172 { 173 bool isErrorMsg = isErrorMsg_; 174 if (isErrorMsg_) { 175 isErrorMsg_ = false; 176 } 177 return isErrorMsg; 178 } 179 GetAndResetFunctionInShared()180 bool GetAndResetFunctionInShared() 181 { 182 bool functionInShared = functionInShared_; 183 if (functionInShared_) { 184 functionInShared_ = false; 185 } 186 return functionInShared; 187 } 188 GetAndResetBufferPointer()189 void *GetAndResetBufferPointer() 190 { 191 if (bufferPointer_) { 192 void *buffer = bufferPointer_; 193 bufferPointer_ = nullptr; 194 return buffer; 195 } 196 return nullptr; 197 } 198 GetAndResetConstantPool()199 ConstantPool *GetAndResetConstantPool() 200 { 201 if (constpool_) { 202 ConstantPool *constpool = constpool_; 203 constpool_ = nullptr; 204 return constpool; 205 } 206 return nullptr; 207 } 208 UpdateMaybeWeak(ObjectSlot slot,uintptr_t addr,bool isWeak)209 void UpdateMaybeWeak(ObjectSlot slot, uintptr_t addr, bool isWeak) 210 { 211 isWeak ? slot.UpdateWeak(addr) : slot.Update(addr); 212 } 213 214 private: 215 JSThread *thread_; 216 Heap *heap_; 217 SerializeData* data_; 218 void *engine_; 219 uintptr_t oldSpaceBeginAddr_ {0}; 220 uintptr_t nonMovableSpaceBeginAddr_ {0}; 221 uintptr_t machineCodeSpaceBeginAddr_ {0}; 222 CVector<uintptr_t> objectVector_; 223 CVector<Region *> regionVector_; 224 size_t oldRegionIndex_ {0}; 225 size_t nonMovableRegionIndex_ {0}; 226 size_t machineCodeRegionIndex_ {0}; 227 size_t regionRemainSizeIndex_ {0}; 228 bool isWeak_ {false}; 229 bool isTransferArrayBuffer_ {false}; 230 bool isErrorMsg_ {false}; 231 void *bufferPointer_ {nullptr}; 232 ConstantPool *constpool_ {nullptr}; 233 bool needNewConstPool_ {false}; 234 bool functionInShared_ {false}; 235 CVector<NewConstPoolInfo *> newConstPoolInfos_; 236 CVector<NativeBindingInfo *> nativeBindingInfos_; 237 CVector<JSErrorInfo *> jsErrorInfos_; 238 CVector<JSFunction *> concurrentFunctions_; 239 }; 240 } 241 242 #endif // ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H