14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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/builtins/builtins_shared_object.h"
174514f5e3Sopenharmony_ci#include "ecmascript/ecma_vm.h"
184514f5e3Sopenharmony_ci#include "ecmascript/global_env.h"
194514f5e3Sopenharmony_ci#include "ecmascript/js_handle.h"
204514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h"
214514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
224514f5e3Sopenharmony_ci
234514f5e3Sopenharmony_ciusing namespace panda::ecmascript;
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_cinamespace panda::test {
264514f5e3Sopenharmony_ciusing BuiltinsSharedObject = ecmascript::builtins::BuiltinsSharedObject;
274514f5e3Sopenharmony_ci
284514f5e3Sopenharmony_ciclass BuiltinsSharedObjectTest : public BaseTestWithScope<false> {
294514f5e3Sopenharmony_ci};
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsSharedObjectTest, SharedObjectConstructor)
324514f5e3Sopenharmony_ci{
334514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
344514f5e3Sopenharmony_ci    JSTaggedValue result = BuiltinsSharedObject::SharedObjectConstructor(ecmaRuntimeCallInfo);
354514f5e3Sopenharmony_ci    ASSERT_EQ(result.GetRawData(), JSTaggedValue::Exception().GetRawData());
364514f5e3Sopenharmony_ci}
374514f5e3Sopenharmony_ci
384514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsSharedObjectTest, SharedObject)
394514f5e3Sopenharmony_ci{
404514f5e3Sopenharmony_ci    DISALLOW_GARBAGE_COLLECTION;
414514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
424514f5e3Sopenharmony_ci    auto globalConst = thread->GlobalConstants();
434514f5e3Sopenharmony_ci    auto sharedObjectPrototype = env->GetSObjectFunctionPrototype();
444514f5e3Sopenharmony_ci    JSHClass *hclass = sharedObjectPrototype->GetTaggedObject()->GetClass();
454514f5e3Sopenharmony_ci    ASSERT_FALSE(hclass->IsExtensible());
464514f5e3Sopenharmony_ci    ASSERT_FALSE(hclass->IsConstructor());
474514f5e3Sopenharmony_ci    ASSERT_FALSE(hclass->IsCallable());
484514f5e3Sopenharmony_ci    ASSERT_TRUE(hclass->IsJSSharedObject());
494514f5e3Sopenharmony_ci    ASSERT_TRUE(hclass->GetProto().IsNull());
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_ci    // SharedObject
524514f5e3Sopenharmony_ci    PropertyDescriptor desc(thread);
534514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
544514f5e3Sopenharmony_ci    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sharedObjectPrototype), constructorKey, desc);
554514f5e3Sopenharmony_ci    auto ctor = desc.GetValue();
564514f5e3Sopenharmony_ci    ASSERT_EQ(ctor.GetTaggedValue(), env->GetSObjectFunction().GetTaggedValue());
574514f5e3Sopenharmony_ci    JSHClass *ctorHClass = ctor->GetTaggedObject()->GetClass();
584514f5e3Sopenharmony_ci    ASSERT_FALSE(ctorHClass->IsExtensible());
594514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsConstructor());
604514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsCallable());
614514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsJSSharedFunction());
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci    // SharedFunction.prototype
644514f5e3Sopenharmony_ci    auto proto = ctorHClass->GetProto();
654514f5e3Sopenharmony_ci    ASSERT_EQ(proto, env->GetSFunctionPrototype().GetTaggedValue());
664514f5e3Sopenharmony_ci    ASSERT_TRUE(proto.IsJSSharedFunction());
674514f5e3Sopenharmony_ci    JSHClass *protoHClass = proto.GetTaggedObject()->GetClass();
684514f5e3Sopenharmony_ci    ASSERT_FALSE(protoHClass->IsExtensible());
694514f5e3Sopenharmony_ci    ASSERT_FALSE(protoHClass->IsConstructor());
704514f5e3Sopenharmony_ci    ASSERT_TRUE(protoHClass->IsCallable());
714514f5e3Sopenharmony_ci
724514f5e3Sopenharmony_ci    // SharedObject.prototype
734514f5e3Sopenharmony_ci    auto sObjProto = protoHClass->GetProto();
744514f5e3Sopenharmony_ci    ASSERT_EQ(sObjProto, sharedObjectPrototype.GetTaggedValue());
754514f5e3Sopenharmony_ci    ASSERT_TRUE(sObjProto.IsJSSharedObject());
764514f5e3Sopenharmony_ci    JSHClass *sObjProtoHClass = sObjProto.GetTaggedObject()->GetClass();
774514f5e3Sopenharmony_ci    ASSERT_FALSE(sObjProtoHClass->IsExtensible());
784514f5e3Sopenharmony_ci    ASSERT_FALSE(sObjProtoHClass->IsConstructor());
794514f5e3Sopenharmony_ci    ASSERT_FALSE(sObjProtoHClass->IsCallable());
804514f5e3Sopenharmony_ci}
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsSharedObjectTest, SharedFunction)
834514f5e3Sopenharmony_ci{
844514f5e3Sopenharmony_ci    DISALLOW_GARBAGE_COLLECTION;
854514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
864514f5e3Sopenharmony_ci    auto globalConst = thread->GlobalConstants();
874514f5e3Sopenharmony_ci    auto sFunctionPrototype = env->GetSFunctionPrototype();
884514f5e3Sopenharmony_ci    // SharedFunction
894514f5e3Sopenharmony_ci    PropertyDescriptor desc(thread);
904514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
914514f5e3Sopenharmony_ci    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sFunctionPrototype), constructorKey, desc);
924514f5e3Sopenharmony_ci    auto ctor = desc.GetValue();
934514f5e3Sopenharmony_ci    ASSERT_EQ(ctor.GetTaggedValue(), env->GetSFunctionFunction().GetTaggedValue());
944514f5e3Sopenharmony_ci    JSHClass *ctorHClass = ctor->GetTaggedObject()->GetClass();
954514f5e3Sopenharmony_ci    ASSERT_FALSE(ctorHClass->IsExtensible());
964514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsConstructor());
974514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsCallable());
984514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsJSSharedFunction());
994514f5e3Sopenharmony_ci
1004514f5e3Sopenharmony_ci    JSHandle<JSHClass> normalFunctionClass(env->GetSFunctionClassWithoutProto());
1014514f5e3Sopenharmony_ci    ASSERT_FALSE(normalFunctionClass->IsExtensible());
1024514f5e3Sopenharmony_ci    ASSERT_FALSE(normalFunctionClass->IsConstructor());
1034514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsCallable());
1044514f5e3Sopenharmony_ci    ASSERT_TRUE(ctorHClass->IsJSSharedFunction());
1054514f5e3Sopenharmony_ci}
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsSharedObjectTest, SharedBuiltinsMethod)
1084514f5e3Sopenharmony_ci{
1094514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1104514f5e3Sopenharmony_ci    auto factory = thread->GetEcmaVM()->GetFactory();
1114514f5e3Sopenharmony_ci    auto sFunctionPrototype = env->GetSFunctionPrototype();
1124514f5e3Sopenharmony_ci    auto callStr = factory->NewFromASCII("call");
1134514f5e3Sopenharmony_ci    PropertyDescriptor desc(thread);
1144514f5e3Sopenharmony_ci    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sFunctionPrototype), JSHandle<JSTaggedValue>(callStr), desc);
1154514f5e3Sopenharmony_ci    auto method = desc.GetValue();
1164514f5e3Sopenharmony_ci    JSHClass *hclass = method->GetTaggedObject()->GetClass();
1174514f5e3Sopenharmony_ci    ASSERT_FALSE(hclass->IsExtensible());
1184514f5e3Sopenharmony_ci    ASSERT_TRUE(!hclass->IsConstructor());
1194514f5e3Sopenharmony_ci    ASSERT_TRUE(hclass->IsCallable());
1204514f5e3Sopenharmony_ci    ASSERT_TRUE(hclass->IsJSSharedFunction());
1214514f5e3Sopenharmony_ci}
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsSharedObjectTest, SendableMethod)
1244514f5e3Sopenharmony_ci{
1254514f5e3Sopenharmony_ci    // Mock create sendable function
1264514f5e3Sopenharmony_ci    auto factory = thread->GetEcmaVM()->GetFactory();
1274514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ci    uint32_t methodOffset = 100;
1304514f5e3Sopenharmony_ci    MethodLiteral *methodLiteral = new MethodLiteral(EntityId(methodOffset));
1314514f5e3Sopenharmony_ci    methodLiteral->SetIsShared(true);
1324514f5e3Sopenharmony_ci    JSHandle<Method> method = factory->NewSMethod(methodLiteral);
1334514f5e3Sopenharmony_ci    method->SetFunctionKind(FunctionKind::BASE_CONSTRUCTOR);
1344514f5e3Sopenharmony_ci    JSHandle<JSFunction> func = factory->NewJSSendableFunction(method);
1354514f5e3Sopenharmony_ci    ASSERT_TRUE(Method::Cast(func->GetMethod())->IsSendableMethod());
1364514f5e3Sopenharmony_ci
1374514f5e3Sopenharmony_ci    uint32_t methodOffset1 = 101;
1384514f5e3Sopenharmony_ci    MethodLiteral *methodLiteral1 = new MethodLiteral(EntityId(methodOffset1));
1394514f5e3Sopenharmony_ci    JSHandle<Method> method1 = factory->NewSMethod(methodLiteral1);
1404514f5e3Sopenharmony_ci    method1->SetIsSendable(true);
1414514f5e3Sopenharmony_ci    JSHandle<JSFunction> func1 = factory->NewSFunctionByHClass(
1424514f5e3Sopenharmony_ci        method1, JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto()));
1434514f5e3Sopenharmony_ci    ASSERT_TRUE(Method::Cast(func1->GetMethod())->IsSendableMethod());
1444514f5e3Sopenharmony_ci}
1454514f5e3Sopenharmony_ci}  // namespace panda::test
146