14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/ic/ic_handler.h"
174514f5e3Sopenharmony_ci#include "ecmascript/ic/proto_change_details.h"
184514f5e3Sopenharmony_ci#include "ecmascript/global_env.h"
194514f5e3Sopenharmony_ci#include "ecmascript/js_array.h"
204514f5e3Sopenharmony_ci#include "ecmascript/js_hclass.h"
214514f5e3Sopenharmony_ci#include "ecmascript/js_object-inl.h"
224514f5e3Sopenharmony_ci#include "ecmascript/object_operator.h"
234514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ciusing namespace panda::ecmascript;
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_cinamespace panda::test {
284514f5e3Sopenharmony_ciusing HandlerKind = ecmascript::HandlerBase::HandlerKind;
294514f5e3Sopenharmony_ciclass ICHandlerTest : public testing::Test {
304514f5e3Sopenharmony_cipublic:
314514f5e3Sopenharmony_ci    static void SetUpTestCase()
324514f5e3Sopenharmony_ci    {
334514f5e3Sopenharmony_ci        GTEST_LOG_(INFO) << "SetUpTestCase";
344514f5e3Sopenharmony_ci    }
354514f5e3Sopenharmony_ci
364514f5e3Sopenharmony_ci    static void TearDownTestCase()
374514f5e3Sopenharmony_ci    {
384514f5e3Sopenharmony_ci        GTEST_LOG_(INFO) << "TearDownCase";
394514f5e3Sopenharmony_ci    }
404514f5e3Sopenharmony_ci
414514f5e3Sopenharmony_ci    void SetUp() override
424514f5e3Sopenharmony_ci    {
434514f5e3Sopenharmony_ci        TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
444514f5e3Sopenharmony_ci    }
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ci    void TearDown() override
474514f5e3Sopenharmony_ci    {
484514f5e3Sopenharmony_ci        TestHelper::DestroyEcmaVMWithScope(instance, scope);
494514f5e3Sopenharmony_ci    }
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_ci    EcmaVM *instance {nullptr};
524514f5e3Sopenharmony_ci    EcmaHandleScope *scope {nullptr};
534514f5e3Sopenharmony_ci    JSThread *thread {nullptr};
544514f5e3Sopenharmony_ci};
554514f5e3Sopenharmony_ci
564514f5e3Sopenharmony_ci/**
574514f5e3Sopenharmony_ci * @tc.name: LoadElement
584514f5e3Sopenharmony_ci * @tc.desc: Call "LoadElement" function,check whether the Element is loaded successfully by checking returned value.
594514f5e3Sopenharmony_ci * @tc.type: FUNC
604514f5e3Sopenharmony_ci * @tc.require:
614514f5e3Sopenharmony_ci */
624514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, LoadElement)
634514f5e3Sopenharmony_ci{
644514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
654514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
664514f5e3Sopenharmony_ci    ObjectOperator handleOp(thread, handleKey);
674514f5e3Sopenharmony_ci    JSTaggedValue result = LoadHandler::LoadElement(thread, handleOp).GetTaggedValue();
684514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsNormalElement(result.GetNumber()));
694514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(result.GetNumber()), HandlerKind::ELEMENT);
704514f5e3Sopenharmony_ci}
714514f5e3Sopenharmony_ci
724514f5e3Sopenharmony_ci/**
734514f5e3Sopenharmony_ci * @tc.name: LoadProperty
744514f5e3Sopenharmony_ci * @tc.desc: Call "LoadProperty" function,check whether the Property is loaded successfully by checking returned value.
754514f5e3Sopenharmony_ci * @tc.type: FUNC
764514f5e3Sopenharmony_ci * @tc.require:
774514f5e3Sopenharmony_ci */
784514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, LoadProperty)
794514f5e3Sopenharmony_ci{
804514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
814514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
824514f5e3Sopenharmony_ci
834514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetArrayFunction();
844514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
854514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
864514f5e3Sopenharmony_ci    int index = 1;
874514f5e3Sopenharmony_ci    PropertyAttributes handleAttriButes(2);
884514f5e3Sopenharmony_ci    handleAttriButes.SetIsInlinedProps(true);
894514f5e3Sopenharmony_ci    // test op is not Found
904514f5e3Sopenharmony_ci    ObjectOperator handleOp1(thread, handleKey);
914514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo1 = LoadHandler::LoadProperty(thread, handleOp1);
924514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsNonExist(handlerInfo1->GetInt()));
934514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo1->GetInt()), HandlerKind::NON_EXIST);
944514f5e3Sopenharmony_ci    // test op is Found and FastMode
954514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleHolder(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
964514f5e3Sopenharmony_ci    ObjectOperator handleOp2(thread, handleHolder, handleKey);
974514f5e3Sopenharmony_ci    handleOp2.SetFastMode(true);
984514f5e3Sopenharmony_ci    handleOp2.SetIndex(index);
994514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo2 = LoadHandler::LoadProperty(thread, handleOp2);
1004514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo2->GetInt()), 1);
1014514f5e3Sopenharmony_ci    // test op is Found and InlinedProps
1024514f5e3Sopenharmony_ci    handleOp2.SetAttr(handleAttriButes);
1034514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo3 = LoadHandler::LoadProperty(thread, handleOp2);
1044514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo3->GetInt()), HandlerKind::FIELD);
1054514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo3->GetInt()), 5);
1064514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsInlinedProps(handlerInfo3->GetInt()));
1074514f5e3Sopenharmony_ci}
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_ci/**
1104514f5e3Sopenharmony_ci * @tc.name: StoreElement
1114514f5e3Sopenharmony_ci * @tc.desc: Call "StoreElement" function,check whether the Element is stored successfully by checking returned value.
1124514f5e3Sopenharmony_ci * @tc.type: FUNC
1134514f5e3Sopenharmony_ci * @tc.require:
1144514f5e3Sopenharmony_ci */
1154514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, StoreElement)
1164514f5e3Sopenharmony_ci{
1174514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1184514f5e3Sopenharmony_ci
1194514f5e3Sopenharmony_ci    JSArray *handleArr = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject<JSArray>();
1204514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleReceiver1(thread, handleArr);
1214514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleReceiver2(factory->NewJSArray());
1224514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
1234514f5e3Sopenharmony_ci
1244514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo1 = StoreHandler::StoreElement(thread, handleReceiver1, 0);
1254514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo2 = StoreHandler::StoreElement(thread, handleReceiver2, 0);
1264514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo3 = StoreHandler::StoreElement(thread, handleValue, 0);
1274514f5e3Sopenharmony_ci
1284514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo1->GetInt()), HandlerKind::ELEMENT);
1294514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo2->GetInt()), HandlerKind::ELEMENT);
1304514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo3->GetInt()), HandlerKind::ELEMENT);
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsJSArray(handlerInfo1->GetInt()));
1334514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsJSArray(handlerInfo2->GetInt()));
1344514f5e3Sopenharmony_ci    EXPECT_FALSE(HandlerBase::IsJSArray(handlerInfo3->GetInt()));
1354514f5e3Sopenharmony_ci}
1364514f5e3Sopenharmony_ci
1374514f5e3Sopenharmony_ci/**
1384514f5e3Sopenharmony_ci * @tc.name: StoreProperty
1394514f5e3Sopenharmony_ci * @tc.desc: Call "StoreProperty" function,check whether the Property is stored successfully by checking returned value.
1404514f5e3Sopenharmony_ci *           according to the ObjectOperation object,the stored Property is different,the stored ObjectOperation object
1414514f5e3Sopenharmony_ci *           is Found.
1424514f5e3Sopenharmony_ci * @tc.type: FUNC
1434514f5e3Sopenharmony_ci * @tc.require:
1444514f5e3Sopenharmony_ci */
1454514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, StoreProperty)
1464514f5e3Sopenharmony_ci{
1474514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1484514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1494514f5e3Sopenharmony_ci
1504514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
1514514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
1524514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
1534514f5e3Sopenharmony_ci    int index = 2;
1544514f5e3Sopenharmony_ci    PropertyAttributes handleAttriButes(2);
1554514f5e3Sopenharmony_ci    handleAttriButes.SetIsInlinedProps(true);
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci    JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
1584514f5e3Sopenharmony_ci    ObjectOperator handleOp1(thread, handleKey);
1594514f5e3Sopenharmony_ci    handleOp1.SetValue(cellHandle.GetTaggedValue());
1604514f5e3Sopenharmony_ci    // test op value is PropertyBox
1614514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo1 = StoreHandler::StoreProperty(thread, handleOp1);
1624514f5e3Sopenharmony_ci    EXPECT_TRUE(handlerInfo1->IsPropertyBox());
1634514f5e3Sopenharmony_ci    // test op is FastMode/Found and not AccessorDescriptor
1644514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleReceiver(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
1654514f5e3Sopenharmony_ci    ObjectOperator handleOp2(thread, handleReceiver, handleKey);
1664514f5e3Sopenharmony_ci    handleOp2.SetFastMode(true);
1674514f5e3Sopenharmony_ci    handleOp2.SetIndex(index);
1684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo2 = StoreHandler::StoreProperty(thread, handleOp2);
1694514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo2->GetInt()), 2);
1704514f5e3Sopenharmony_ci    EXPECT_FALSE(HandlerBase::IsAccessor(handlerInfo2->GetInt()));
1714514f5e3Sopenharmony_ci    // test op is InlinedProps/Found and not AccessorDescriptor
1724514f5e3Sopenharmony_ci    handleOp2.SetAttr(handleAttriButes);
1734514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo3 = StoreHandler::StoreProperty(thread, handleOp2);
1744514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetKind(handlerInfo3->GetInt()), HandlerKind::FIELD);
1754514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo3->GetInt()), 6);
1764514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsInlinedProps(handlerInfo3->GetInt()));
1774514f5e3Sopenharmony_ci}
1784514f5e3Sopenharmony_ci
1794514f5e3Sopenharmony_ci/**
1804514f5e3Sopenharmony_ci * @tc.name: StoreTransition
1814514f5e3Sopenharmony_ci * @tc.desc: Call "StoreTransition" function,check whether the Transition is stored successfully by checking
1824514f5e3Sopenharmony_ci *           returned value.
1834514f5e3Sopenharmony_ci * @tc.type: FUNC
1844514f5e3Sopenharmony_ci * @tc.require:
1854514f5e3Sopenharmony_ci */
1864514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, StoreTransition)
1874514f5e3Sopenharmony_ci{
1884514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1894514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1904514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
1914514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
1924514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
1934514f5e3Sopenharmony_ci
1944514f5e3Sopenharmony_ci    JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
1954514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleHolder(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
1964514f5e3Sopenharmony_ci
1974514f5e3Sopenharmony_ci    ObjectOperator handleOp(thread, handleHolder, handleKey);
1984514f5e3Sopenharmony_ci    handleOp.SetValue(cellHandle.GetTaggedValue());
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerValue = TransitionHandler::StoreTransition(thread, handleOp);
2014514f5e3Sopenharmony_ci    JSHandle<TransitionHandler> handler = JSHandle<TransitionHandler>::Cast(handlerValue);
2024514f5e3Sopenharmony_ci    EXPECT_TRUE(handler->GetHandlerInfo().IsPropertyBox());
2034514f5e3Sopenharmony_ci    EXPECT_TRUE(handler->GetTransitionHClass().IsHeapObject());
2044514f5e3Sopenharmony_ci}
2054514f5e3Sopenharmony_ci
2064514f5e3Sopenharmony_ci/**
2074514f5e3Sopenharmony_ci * @tc.name: LoadPrototype
2084514f5e3Sopenharmony_ci * @tc.desc: Call "LoadPrototype" function,check whether the Prototype is loaded successfully by checking returned value
2094514f5e3Sopenharmony_ci *           according to the ObjectOperation object,the stored Property is different.
2104514f5e3Sopenharmony_ci * @tc.type: FUNC
2114514f5e3Sopenharmony_ci * @tc.require:
2124514f5e3Sopenharmony_ci */
2134514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, LoadPrototype)
2144514f5e3Sopenharmony_ci{
2154514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2164514f5e3Sopenharmony_ci
2174514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
2184514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
2194514f5e3Sopenharmony_ci
2204514f5e3Sopenharmony_ci    JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
2214514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj1 = JSObject::ObjectCreate(thread, nullHandle);
2224514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj2 = JSObject::ObjectCreate(thread, handleObj1);
2234514f5e3Sopenharmony_ci
2244514f5e3Sopenharmony_ci    JSHandle<JSHClass> obj1Class(thread, handleObj1->GetJSHClass());
2254514f5e3Sopenharmony_ci    JSHandle<JSHClass> obj2Class(thread, handleObj2->GetJSHClass());
2264514f5e3Sopenharmony_ci
2274514f5e3Sopenharmony_ci    ObjectOperator handleOp1(thread, handleKey, OperatorType::OWN);
2284514f5e3Sopenharmony_ci    ObjectOperator handleOp2(thread, handleKey, OperatorType::OWN);
2294514f5e3Sopenharmony_ci    handleOp1.SetFastMode(true);
2304514f5e3Sopenharmony_ci    handleOp2.SetFastMode(true);
2314514f5e3Sopenharmony_ci    handleOp2.SetIndex(2);
2324514f5e3Sopenharmony_ci    // test op is not Found and hclass has no Prototype
2334514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerValue1 = LoadHandler::LoadProperty(thread, handleOp1);
2344514f5e3Sopenharmony_ci    EXPECT_TRUE(HandlerBase::IsNonExist(handlerValue1->GetInt()));
2354514f5e3Sopenharmony_ci    // test op is Found and hclass has Prototype
2364514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerValue2 = PrototypeHandler::LoadPrototype(thread, handleOp2, obj2Class);
2374514f5e3Sopenharmony_ci    JSHandle<PrototypeHandler> handler2 = JSHandle<PrototypeHandler>::Cast(handlerValue2);
2384514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo2(thread, handler2->GetHandlerInfo());
2394514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo2->GetInt()), 2);
2404514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> resultMarker(thread, handler2->GetProtoCell());
2414514f5e3Sopenharmony_ci    EXPECT_TRUE(resultMarker->IsProtoChangeMarker());
2424514f5e3Sopenharmony_ci    EXPECT_TRUE(handler2->GetHolder().IsJSGlobalObject());
2434514f5e3Sopenharmony_ci}
2444514f5e3Sopenharmony_ci
2454514f5e3Sopenharmony_ci/**
2464514f5e3Sopenharmony_ci * @tc.name: StorePrototype
2474514f5e3Sopenharmony_ci * @tc.desc: Call StorePrototype function,check whether the Prototype is stored successfully by checking returned value
2484514f5e3Sopenharmony_ci *           according to the ObjectOperation object,the stored Property is different.the stored ObjectOperation object
2494514f5e3Sopenharmony_ci *           must be Found.
2504514f5e3Sopenharmony_ci * @tc.type: FUNC
2514514f5e3Sopenharmony_ci * @tc.require:
2524514f5e3Sopenharmony_ci */
2534514f5e3Sopenharmony_ciHWTEST_F_L0(ICHandlerTest, StorePrototype)
2544514f5e3Sopenharmony_ci{
2554514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2564514f5e3Sopenharmony_ci
2574514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
2584514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
2594514f5e3Sopenharmony_ci
2604514f5e3Sopenharmony_ci    JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
2614514f5e3Sopenharmony_ci    JSHandle<JSObject> nullObj = JSObject::ObjectCreate(thread, nullHandle);
2624514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj = JSObject::ObjectCreate(thread, nullObj);
2634514f5e3Sopenharmony_ci
2644514f5e3Sopenharmony_ci    JSHandle<JSHClass> objClass(thread, handleObj->GetJSHClass());
2654514f5e3Sopenharmony_ci
2664514f5e3Sopenharmony_ci    ObjectOperator handleOp(thread, handleKey, OperatorType::OWN);
2674514f5e3Sopenharmony_ci    handleOp.SetFastMode(true);
2684514f5e3Sopenharmony_ci    handleOp.SetIndex(2);
2694514f5e3Sopenharmony_ci    // test hclass has Prototype
2704514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerValue = PrototypeHandler::StorePrototype(thread, handleOp, objClass);
2714514f5e3Sopenharmony_ci    JSHandle<PrototypeHandler> handler = JSHandle<PrototypeHandler>::Cast(handlerValue);
2724514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handlerInfo(thread, handler->GetHandlerInfo());
2734514f5e3Sopenharmony_ci    EXPECT_EQ(HandlerBase::GetOffset(handlerInfo->GetInt()), 2);
2744514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> resultMarker(thread, handler->GetProtoCell());
2754514f5e3Sopenharmony_ci    EXPECT_TRUE(resultMarker->IsProtoChangeMarker());
2764514f5e3Sopenharmony_ci    EXPECT_TRUE(handler->GetHolder().IsJSGlobalObject());
2774514f5e3Sopenharmony_ci}
2784514f5e3Sopenharmony_ci} // namespace panda::test
279