• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "runtime/dyn_class_linker_extension.h"
17 #include "runtime/include/class_linker-inl.h"
18 #include "runtime/include/class_linker.h"
19 #include "runtime/include/coretypes/array.h"
20 #include "runtime/include/coretypes/class.h"
21 #include "runtime/include/coretypes/dyn_objects.h"
22 #include "runtime/include/coretypes/native_pointer.h"
23 #include "runtime/include/panda_vm.h"
24 
25 namespace panda {
26 using Array = coretypes::Array;
27 using NativePointer = coretypes::NativePointer;
28 
29 using Type = panda_file::Type;
30 using SourceLang = panda_file::SourceLang;
31 
~DynamicClassLinkerExtension()32 DynamicClassLinkerExtension::~DynamicClassLinkerExtension()
33 {
34     if (!IsInitialized()) {
35         return;
36     }
37 
38     FreeLoadedClasses();
39 }
40 
InitializeImpl(bool cmpStrEnabled)41 bool DynamicClassLinkerExtension::InitializeImpl([[maybe_unused]] bool cmpStrEnabled)
42 {
43     LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(GetLanguage());
44 
45     auto *classClass = CreateClass(ctx.GetClassClassDescriptor(), GetClassVTableSize(ClassRoot::CLASS),
46                                    GetClassIMTSize(ClassRoot::CLASS), GetClassSize(ClassRoot::CLASS));
47     coretypes::Class::FromRuntimeClass(classClass)->SetClass(classClass);
48     classClass->SetSourceLang(SourceLang::ECMASCRIPT);
49     classClass->SetState(Class::State::LOADED);
50     classClass->SetLoadContext(GetBootContext());
51     GetClassLinker()->AddClassRoot(ClassRoot::CLASS, classClass);
52 
53     auto *objClass = CreateClass(ctx.GetObjectClassDescriptor(), GetClassVTableSize(ClassRoot::OBJECT),
54                                  GetClassIMTSize(ClassRoot::OBJECT), GetClassSize(ClassRoot::OBJECT));
55     objClass->SetObjectSize(ObjectHeader::ObjectHeaderSize());
56     objClass->SetSourceLang(SourceLang::ECMASCRIPT);
57     classClass->SetBase(objClass);
58     objClass->SetState(Class::State::LOADED);
59     objClass->SetLoadContext(GetBootContext());
60     GetClassLinker()->AddClassRoot(ClassRoot::OBJECT, objClass);
61     return true;
62 }
63 
InitializeArrayClass(Class * arrayClass,Class * componentClass)64 void DynamicClassLinkerExtension::InitializeArrayClass(Class *arrayClass, Class *componentClass)
65 {
66     ASSERT(IsInitialized());
67 
68     auto *objectClass = GetClassRoot(ClassRoot::OBJECT);
69     arrayClass->SetBase(objectClass);
70     arrayClass->SetComponentType(componentClass);
71     uint32_t access_flags = componentClass->GetAccessFlags() & ACC_FILE_MASK;
72     access_flags &= ~ACC_INTERFACE;
73     access_flags |= ACC_FINAL | ACC_ABSTRACT;
74     arrayClass->SetAccessFlags(access_flags);
75     arrayClass->SetState(Class::State::INITIALIZED);
76 }
77 
InitializePrimitiveClass(Class * primitiveClass)78 void DynamicClassLinkerExtension::InitializePrimitiveClass(Class *primitiveClass)
79 {
80     ASSERT(IsInitialized());
81 
82     primitiveClass->SetAccessFlags(ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT);
83     primitiveClass->SetState(Class::State::INITIALIZED);
84 }
85 
GetClassVTableSize(ClassRoot root)86 size_t DynamicClassLinkerExtension::GetClassVTableSize([[maybe_unused]] ClassRoot root)
87 {
88     ASSERT(IsInitialized());
89     return 0;
90 }
91 
GetClassIMTSize(ClassRoot root)92 size_t DynamicClassLinkerExtension::GetClassIMTSize([[maybe_unused]] ClassRoot root)
93 {
94     ASSERT(IsInitialized());
95     return 0;
96 }
97 
GetClassSize(ClassRoot root)98 size_t DynamicClassLinkerExtension::GetClassSize(ClassRoot root)
99 {
100     ASSERT(IsInitialized());
101 
102     switch (root) {
103         case ClassRoot::U1:
104         case ClassRoot::I8:
105         case ClassRoot::U8:
106         case ClassRoot::I16:
107         case ClassRoot::U16:
108         case ClassRoot::I32:
109         case ClassRoot::U32:
110         case ClassRoot::I64:
111         case ClassRoot::U64:
112         case ClassRoot::F32:
113         case ClassRoot::F64:
114         case ClassRoot::TAGGED:
115             return ClassHelper::ComputeClassSize(GetClassVTableSize(root), GetClassIMTSize(root), 0, 0, 0, 0, 0, 0);
116         case ClassRoot::ARRAY_U1:
117         case ClassRoot::ARRAY_I8:
118         case ClassRoot::ARRAY_U8:
119         case ClassRoot::ARRAY_I16:
120         case ClassRoot::ARRAY_U16:
121         case ClassRoot::ARRAY_I32:
122         case ClassRoot::ARRAY_U32:
123         case ClassRoot::ARRAY_I64:
124         case ClassRoot::ARRAY_U64:
125         case ClassRoot::ARRAY_F32:
126         case ClassRoot::ARRAY_F64:
127         case ClassRoot::ARRAY_TAGGED:
128         case ClassRoot::ARRAY_CLASS:
129         case ClassRoot::ARRAY_STRING:
130             return GetArrayClassSize();
131         case ClassRoot::OBJECT:
132         case ClassRoot::CLASS:
133         case ClassRoot::STRING:
134             return ClassHelper::ComputeClassSize(GetClassVTableSize(root), GetClassIMTSize(root), 0, 0, 0, 0, 0, 0);
135         default: {
136             UNREACHABLE();
137             break;
138         }
139     }
140 
141     return 0;
142 }
143 
GetArrayClassVTableSize()144 size_t DynamicClassLinkerExtension::GetArrayClassVTableSize()
145 {
146     ASSERT(IsInitialized());
147 
148     return GetClassVTableSize(ClassRoot::OBJECT);
149 }
150 
GetArrayClassSize()151 size_t DynamicClassLinkerExtension::GetArrayClassSize()
152 {
153     ASSERT(IsInitialized());
154 
155     return GetClassSize(ClassRoot::OBJECT);
156 }
157 
CreateClass(const uint8_t * descriptor,size_t vtableSize,size_t imt_size,size_t size)158 Class *DynamicClassLinkerExtension::CreateClass(const uint8_t *descriptor, size_t vtableSize, size_t imt_size,
159                                                 size_t size)
160 {
161     ASSERT(IsInitialized());
162 
163     auto vm = Thread::GetCurrent()->GetVM();
164     auto *heap_manager = vm->GetHeapManager();
165     auto object_header =
166         heap_manager->AllocateNonMovableObject(GetClassRoot(ClassRoot::CLASS), coretypes::Class::GetSize(size));
167     // CODECHECK-NOLINTNEXTLINE(CPP_RULE_ID_SMARTPOINTER_INSTEADOF_ORIGINPOINTER)
168     auto *res = reinterpret_cast<coretypes::Class *>(object_header);
169     res->InitClass(descriptor, vtableSize, imt_size, size);
170     auto *klass = res->GetRuntimeClass();
171     klass->SetManagedObject(res);
172     klass->SetSourceLang(GetLanguage());
173     return klass;
174 }
175 
FreeClass(Class * klass)176 void DynamicClassLinkerExtension::FreeClass(Class *klass)
177 {
178     ASSERT(IsInitialized());
179 
180     auto *cls = coretypes::Class::FromRuntimeClass(klass);
181     auto allocator = GetClassLinker()->GetAllocator();
182     allocator->Free(cls);
183 }
184 
OnError(ClassLinker::Error error,const PandaString & message)185 void DynamicClassLinkerExtension::ErrorHandler::OnError([[maybe_unused]] ClassLinker::Error error,
186                                                         [[maybe_unused]] const PandaString &message)
187 {
188 }
189 }  // namespace panda
190