* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/compiler/aot_constantpool_patcher.h"
namespace panda::ecmascript {
void AotConstantpoolPatcher::SetPrototypeForTransitions(JSThread *thread, JSHClass *hclass, JSTaggedValue proto)
{
std::queue<JSHClass *> backHClass;
backHClass.push(hclass);
while (!backHClass.empty()) {
JSHClass *current = backHClass.front();
backHClass.pop();
hclass->SetProto(thread, proto);
auto transitions = current->GetTransitions(thread);
if (transitions.IsUndefined()) {
continue;
}
if (transitions.IsWeak()) {
auto cache = transitions.GetTaggedWeakRef();
backHClass.push(JSHClass::Cast(cache));
continue;
}
ASSERT(transitions.IsTaggedArray());
TransitionsDictionary *dict = TransitionsDictionary::Cast(transitions.GetTaggedObject());
dict->IterateEntryValue(thread, [&backHClass] (JSHClass *cache) {
backHClass.push(JSHClass::Cast(cache));
});
}
}
void AotConstantpoolPatcher::SetObjectFunctionFromConstPool(JSThread *thread, JSHandle<ConstantPool> newConstPool)
{
auto aotHCInfo = newConstPool->GetAotHClassInfo(thread);
if (!aotHCInfo.IsTaggedArray()) {
return;
}
auto aotHCInfoArray = TaggedArray::Cast(aotHCInfo);
if (aotHCInfoArray->GetLength() <= 0) {
return;
}
JSTaggedValue ihc = aotHCInfoArray->Get(thread, 0);
if (!ihc.IsJSHClass()) {
return;
}
JSHandle<JSHClass> objectFunctionIHC(thread, ihc);
if (!objectFunctionIHC->IsOnlyJSObject()) {
LOG_ECMA(FATAL) << "Napi Object must be JSObject.";
UNREACHABLE();
return;
}
auto env = thread->GetGlobalEnv();
if (env->GetObjectFunctionTsNapiClass() == env->GetObjectFunctionNapiClass()) {
JSHandle<JSHClass> objectFunctionNapiClass(env->GetObjectFunctionNapiClass());
objectFunctionIHC->SetPrototype(thread, objectFunctionNapiClass->GetProto(thread));
JSHClass::EnableProtoChangeMarker(thread, objectFunctionIHC);
SetPrototypeForTransitions(thread, *objectFunctionIHC, objectFunctionNapiClass->GetProto(thread));
env->SetObjectFunctionTsNapiClass(thread, objectFunctionIHC.GetTaggedValue());
}
}
}