• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 <string>
17 
18 #include "ets_runtime_interface.h"
19 #include "plugins/ets/runtime/ets_class_linker_extension.h"
20 
21 namespace panda::ets {
GetClass(MethodPtr method,IdType id) const22 compiler::RuntimeInterface::ClassPtr EtsRuntimeInterface::GetClass(MethodPtr method, IdType id) const
23 {
24     if (id == RuntimeInterface::MEM_PROMISE_CLASS_ID) {
25         ScopedMutatorLock lock;
26         auto *caller = MethodCast(method);
27         LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(*caller);
28         return static_cast<EtsClassLinkerExtension *>(Runtime::GetCurrent()->GetClassLinker()->GetExtension(ctx))
29             ->GetPromiseClass();
30     }
31     return PandaRuntimeInterface::GetClass(method, id);
32 }
33 
ResolveLookUpField(FieldPtr rawField,ClassPtr klass)34 compiler::RuntimeInterface::FieldPtr EtsRuntimeInterface::ResolveLookUpField(FieldPtr rawField, ClassPtr klass)
35 {
36     ScopedMutatorLock lock;
37     ASSERT(rawField != nullptr);
38     ASSERT(klass != nullptr);
39     return ClassCast(klass)->LookupFieldByName(FieldCast(rawField)->GetName());
40 }
41 
42 template <panda_file::Type::TypeId FIELD_TYPE>
GetLookUpCall(FieldPtr rawField,ClassPtr klass,bool isSetter)43 compiler::RuntimeInterface::MethodPtr EtsRuntimeInterface::GetLookUpCall(FieldPtr rawField, ClassPtr klass,
44                                                                          bool isSetter)
45 {
46     if (isSetter) {
47         return ClassCast(klass)->LookupSetterByName<FIELD_TYPE>(FieldCast(rawField)->GetName());
48     }
49     return ClassCast(klass)->LookupGetterByName<FIELD_TYPE>(FieldCast(rawField)->GetName());
50 }
51 
ResolveLookUpCall(FieldPtr rawField,ClassPtr klass,bool isSetter)52 compiler::RuntimeInterface::MethodPtr EtsRuntimeInterface::ResolveLookUpCall(FieldPtr rawField, ClassPtr klass,
53                                                                              bool isSetter)
54 {
55     ScopedMutatorLock lock;
56     ASSERT(rawField != nullptr);
57     ASSERT(klass != nullptr);
58     switch (FieldCast(rawField)->GetTypeId()) {
59         case panda_file::Type::TypeId::U1:
60             return GetLookUpCall<panda_file::Type::TypeId::U1>(rawField, klass, isSetter);
61         case panda_file::Type::TypeId::U8:
62             return GetLookUpCall<panda_file::Type::TypeId::U8>(rawField, klass, isSetter);
63         case panda_file::Type::TypeId::I8:
64             return GetLookUpCall<panda_file::Type::TypeId::I8>(rawField, klass, isSetter);
65         case panda_file::Type::TypeId::I16:
66             return GetLookUpCall<panda_file::Type::TypeId::I16>(rawField, klass, isSetter);
67         case panda_file::Type::TypeId::U16:
68             return GetLookUpCall<panda_file::Type::TypeId::U16>(rawField, klass, isSetter);
69         case panda_file::Type::TypeId::I32:
70             return GetLookUpCall<panda_file::Type::TypeId::I32>(rawField, klass, isSetter);
71         case panda_file::Type::TypeId::U32:
72             return GetLookUpCall<panda_file::Type::TypeId::U32>(rawField, klass, isSetter);
73         case panda_file::Type::TypeId::I64:
74             return GetLookUpCall<panda_file::Type::TypeId::I64>(rawField, klass, isSetter);
75         case panda_file::Type::TypeId::U64:
76             return GetLookUpCall<panda_file::Type::TypeId::U64>(rawField, klass, isSetter);
77         case panda_file::Type::TypeId::F32:
78             return GetLookUpCall<panda_file::Type::TypeId::F32>(rawField, klass, isSetter);
79         case panda_file::Type::TypeId::F64:
80             return GetLookUpCall<panda_file::Type::TypeId::F64>(rawField, klass, isSetter);
81         case panda_file::Type::TypeId::REFERENCE:
82             return GetLookUpCall<panda_file::Type::TypeId::REFERENCE>(rawField, klass, isSetter);
83         default: {
84             UNREACHABLE();
85             break;
86         }
87     }
88     return nullptr;
89 }
90 
GetUndefinedObject() const91 uint64_t EtsRuntimeInterface::GetUndefinedObject() const
92 {
93     return ToUintPtr(PandaEtsVM::GetCurrent()->GetUndefinedObject());
94 }
95 
GetInteropCallKind(MethodPtr methodPtr) const96 compiler::RuntimeInterface::InteropCallKind EtsRuntimeInterface::GetInteropCallKind(MethodPtr methodPtr) const
97 {
98     auto className = GetClassNameFromMethod(methodPtr);
99     auto classNameSuffix = className.substr(className.find_last_of('.') + 1);
100     if (classNameSuffix == "$jsnew") {
101         return InteropCallKind::NEW_INSTANCE;
102     }
103     if (classNameSuffix != "$jscall") {
104         return InteropCallKind::UNKNOWN;
105     }
106 
107     auto method = MethodCast(methodPtr);
108     auto pf = method->GetPandaFile();
109     panda_file::ProtoDataAccessor pda(*pf, panda_file::MethodDataAccessor::GetProtoId(*pf, method->GetFileId()));
110 
111     ClassLinker *classLinker = Runtime::GetCurrent()->GetClassLinker();
112     LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(*method);
113     auto linkerCtx = static_cast<EtsClassLinkerExtension *>(classLinker->GetExtension(ctx))->GetBootContext();
114 
115     ScopedMutatorLock lock;
116 
117     ASSERT(method->GetArgType(0).IsReference());  // arg0 is always a reference
118     ASSERT(method->GetArgType(1).IsReference());  // arg1 is always a reference
119     uint32_t const argReftypeShift = method->GetReturnType().IsReference() ? 1 : 0;
120     auto cls = classLinker->GetClass(*pf, pda.GetReferenceType(1 + argReftypeShift), linkerCtx);
121     if (cls->IsStringClass()) {
122         return InteropCallKind::CALL;
123     }
124     return InteropCallKind::CALL_BY_VALUE;
125 }
126 
GetFuncPropName(MethodPtr methodPtr,uint32_t strId) const127 char *EtsRuntimeInterface::GetFuncPropName(MethodPtr methodPtr, uint32_t strId) const
128 {
129     auto method = MethodCast(methodPtr);
130     auto pf = method->GetPandaFile();
131     auto str = reinterpret_cast<const char *>(pf->GetStringData(panda::panda_file::File::EntityId(strId)).data);
132     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
133     return const_cast<char *>(std::strrchr(str, '.') + 1);
134 }
135 
GetFuncPropNameOffset(MethodPtr methodPtr,uint32_t strId) const136 uint64_t EtsRuntimeInterface::GetFuncPropNameOffset(MethodPtr methodPtr, uint32_t strId) const
137 {
138     auto pf = MethodCast(methodPtr)->GetPandaFile();
139     auto str = GetFuncPropName(methodPtr, strId);
140     return reinterpret_cast<uint64_t>(str) - reinterpret_cast<uint64_t>(pf->GetBase());
141 }
142 
IsMethodStringBuilderConstructorWithStringArg(MethodPtr method) const143 bool EtsRuntimeInterface::IsMethodStringBuilderConstructorWithStringArg(MethodPtr method) const
144 {
145     return MethodCast(method)->IsConstructor() && GetClassNameFromMethod(method) == "std.core.StringBuilder" &&
146            MethodCast(method)->GetProto().GetSignature() == "(Lstd/core/String;)V";
147 }
148 
IsMethodStringBuilderToString(MethodPtr method) const149 bool EtsRuntimeInterface::IsMethodStringBuilderToString(MethodPtr method) const
150 {
151     return GetMethodFullName(method, false) == "std.core.StringBuilder::toString" &&
152            MethodCast(method)->GetProto().GetSignature() == "()Lstd/core/String;";
153 }
154 
IsIntrinsicStringBuilderToString(IntrinsicId id) const155 bool EtsRuntimeInterface::IsIntrinsicStringBuilderToString(IntrinsicId id) const
156 {
157     return id == RuntimeInterface::IntrinsicId::INTRINSIC_STD_CORE_SB_TO_STRING;
158 }
159 
160 }  // namespace panda::ets
161