1 /** 2 * Copyright (c) 2024 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 PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CALL_PROTO_READER_H 17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CALL_PROTO_READER_H 18 19 #include "runtime/include/class_linker-inl.h" 20 #include "libpandafile/proto_data_accessor-inl.h" 21 22 namespace ark::ets::interop::js { 23 24 class ProtoReader { 25 public: ProtoReader(Method * method,ClassLinker * classLinker,ClassLinkerContext * classLinkerContext)26 ALWAYS_INLINE ProtoReader(Method *method, ClassLinker *classLinker, ClassLinkerContext *classLinkerContext) 27 : method_(method), 28 pf_(method_->GetPandaFile()), 29 pda_(*pf_, panda_file::MethodDataAccessor::GetProtoId(*pf_, method_->GetFileId())), 30 classLinker_(classLinker), 31 classLinkerContext_(classLinkerContext) 32 { 33 pda_.EnumerateTypes([](panda_file::Type) {}); // preload reftypes span 34 Reset(); 35 } 36 Reset()37 ALWAYS_INLINE void Reset() 38 { 39 it_ = panda_file::ShortyIterator(method_->GetShorty()); 40 refArgIdx_ = 0; 41 } 42 Advance()43 ALWAYS_INLINE void Advance() 44 { 45 if (GetType().IsReference()) { 46 refArgIdx_++; 47 } 48 it_.IncrementWithoutCheck(); 49 } 50 GetType()51 ALWAYS_INLINE panda_file::Type GetType() 52 { 53 return *it_; 54 } 55 GetClass()56 ALWAYS_INLINE Class *GetClass() 57 { 58 ASSERT(GetType().IsReference()); 59 return ResolveProtoClass(refArgIdx_); 60 } 61 GetLoadedClass()62 ALWAYS_INLINE Class *GetLoadedClass() 63 { 64 ASSERT(GetType().IsReference()); 65 return ResolveLoadedProtoClass(refArgIdx_); 66 } 67 ResolveLoadedProtoClass(uint32_t idx)68 ALWAYS_INLINE Class *ResolveLoadedProtoClass(uint32_t idx) 69 { 70 auto klass = classLinker_->GetLoadedClass(*pf_, pda_.GetReferenceType(idx), classLinkerContext_); 71 ASSERT(klass != nullptr); 72 return klass; 73 } 74 ResolveProtoClass(uint32_t idx)75 ALWAYS_INLINE Class *ResolveProtoClass(uint32_t idx) 76 { 77 return classLinker_->GetClass(*pf_, pda_.GetReferenceType(idx), classLinkerContext_); 78 } 79 GetMethod()80 ALWAYS_INLINE Method *GetMethod() 81 { 82 return method_; 83 } 84 GetMethod()85 ALWAYS_INLINE const Method *GetMethod() const 86 { 87 return method_; 88 } 89 90 private: 91 panda_file::ShortyIterator it_ {}; 92 uint32_t refArgIdx_ {}; 93 94 Method *const method_; 95 panda_file::File const *const pf_; 96 panda_file::ProtoDataAccessor pda_; 97 98 ClassLinker *const classLinker_; 99 ClassLinkerContext *const classLinkerContext_; 100 }; 101 102 } // namespace ark::ets::interop::js 103 104 #endif // PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CALL_PROTO_READER_H 105