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