1/* 2 * Copyright (c) 2023 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 "ecmascript/builtins/builtins_shared_object.h" 17#include "ecmascript/ecma_vm.h" 18#include "ecmascript/global_env.h" 19#include "ecmascript/js_handle.h" 20#include "ecmascript/js_tagged_value.h" 21#include "ecmascript/tests/test_helper.h" 22 23using namespace panda::ecmascript; 24 25namespace panda::test { 26using BuiltinsSharedObject = ecmascript::builtins::BuiltinsSharedObject; 27 28class BuiltinsSharedObjectTest : public BaseTestWithScope<false> { 29}; 30 31HWTEST_F_L0(BuiltinsSharedObjectTest, SharedObjectConstructor) 32{ 33 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 34 JSTaggedValue result = BuiltinsSharedObject::SharedObjectConstructor(ecmaRuntimeCallInfo); 35 ASSERT_EQ(result.GetRawData(), JSTaggedValue::Exception().GetRawData()); 36} 37 38HWTEST_F_L0(BuiltinsSharedObjectTest, SharedObject) 39{ 40 DISALLOW_GARBAGE_COLLECTION; 41 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 42 auto globalConst = thread->GlobalConstants(); 43 auto sharedObjectPrototype = env->GetSObjectFunctionPrototype(); 44 JSHClass *hclass = sharedObjectPrototype->GetTaggedObject()->GetClass(); 45 ASSERT_FALSE(hclass->IsExtensible()); 46 ASSERT_FALSE(hclass->IsConstructor()); 47 ASSERT_FALSE(hclass->IsCallable()); 48 ASSERT_TRUE(hclass->IsJSSharedObject()); 49 ASSERT_TRUE(hclass->GetProto().IsNull()); 50 51 // SharedObject 52 PropertyDescriptor desc(thread); 53 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString(); 54 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sharedObjectPrototype), constructorKey, desc); 55 auto ctor = desc.GetValue(); 56 ASSERT_EQ(ctor.GetTaggedValue(), env->GetSObjectFunction().GetTaggedValue()); 57 JSHClass *ctorHClass = ctor->GetTaggedObject()->GetClass(); 58 ASSERT_FALSE(ctorHClass->IsExtensible()); 59 ASSERT_TRUE(ctorHClass->IsConstructor()); 60 ASSERT_TRUE(ctorHClass->IsCallable()); 61 ASSERT_TRUE(ctorHClass->IsJSSharedFunction()); 62 63 // SharedFunction.prototype 64 auto proto = ctorHClass->GetProto(); 65 ASSERT_EQ(proto, env->GetSFunctionPrototype().GetTaggedValue()); 66 ASSERT_TRUE(proto.IsJSSharedFunction()); 67 JSHClass *protoHClass = proto.GetTaggedObject()->GetClass(); 68 ASSERT_FALSE(protoHClass->IsExtensible()); 69 ASSERT_FALSE(protoHClass->IsConstructor()); 70 ASSERT_TRUE(protoHClass->IsCallable()); 71 72 // SharedObject.prototype 73 auto sObjProto = protoHClass->GetProto(); 74 ASSERT_EQ(sObjProto, sharedObjectPrototype.GetTaggedValue()); 75 ASSERT_TRUE(sObjProto.IsJSSharedObject()); 76 JSHClass *sObjProtoHClass = sObjProto.GetTaggedObject()->GetClass(); 77 ASSERT_FALSE(sObjProtoHClass->IsExtensible()); 78 ASSERT_FALSE(sObjProtoHClass->IsConstructor()); 79 ASSERT_FALSE(sObjProtoHClass->IsCallable()); 80} 81 82HWTEST_F_L0(BuiltinsSharedObjectTest, SharedFunction) 83{ 84 DISALLOW_GARBAGE_COLLECTION; 85 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 86 auto globalConst = thread->GlobalConstants(); 87 auto sFunctionPrototype = env->GetSFunctionPrototype(); 88 // SharedFunction 89 PropertyDescriptor desc(thread); 90 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString(); 91 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sFunctionPrototype), constructorKey, desc); 92 auto ctor = desc.GetValue(); 93 ASSERT_EQ(ctor.GetTaggedValue(), env->GetSFunctionFunction().GetTaggedValue()); 94 JSHClass *ctorHClass = ctor->GetTaggedObject()->GetClass(); 95 ASSERT_FALSE(ctorHClass->IsExtensible()); 96 ASSERT_TRUE(ctorHClass->IsConstructor()); 97 ASSERT_TRUE(ctorHClass->IsCallable()); 98 ASSERT_TRUE(ctorHClass->IsJSSharedFunction()); 99 100 JSHandle<JSHClass> normalFunctionClass(env->GetSFunctionClassWithoutProto()); 101 ASSERT_FALSE(normalFunctionClass->IsExtensible()); 102 ASSERT_FALSE(normalFunctionClass->IsConstructor()); 103 ASSERT_TRUE(ctorHClass->IsCallable()); 104 ASSERT_TRUE(ctorHClass->IsJSSharedFunction()); 105} 106 107HWTEST_F_L0(BuiltinsSharedObjectTest, SharedBuiltinsMethod) 108{ 109 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 110 auto factory = thread->GetEcmaVM()->GetFactory(); 111 auto sFunctionPrototype = env->GetSFunctionPrototype(); 112 auto callStr = factory->NewFromASCII("call"); 113 PropertyDescriptor desc(thread); 114 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(sFunctionPrototype), JSHandle<JSTaggedValue>(callStr), desc); 115 auto method = desc.GetValue(); 116 JSHClass *hclass = method->GetTaggedObject()->GetClass(); 117 ASSERT_FALSE(hclass->IsExtensible()); 118 ASSERT_TRUE(!hclass->IsConstructor()); 119 ASSERT_TRUE(hclass->IsCallable()); 120 ASSERT_TRUE(hclass->IsJSSharedFunction()); 121} 122 123HWTEST_F_L0(BuiltinsSharedObjectTest, SendableMethod) 124{ 125 // Mock create sendable function 126 auto factory = thread->GetEcmaVM()->GetFactory(); 127 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 128 129 uint32_t methodOffset = 100; 130 MethodLiteral *methodLiteral = new MethodLiteral(EntityId(methodOffset)); 131 methodLiteral->SetIsShared(true); 132 JSHandle<Method> method = factory->NewSMethod(methodLiteral); 133 method->SetFunctionKind(FunctionKind::BASE_CONSTRUCTOR); 134 JSHandle<JSFunction> func = factory->NewJSSendableFunction(method); 135 ASSERT_TRUE(Method::Cast(func->GetMethod())->IsSendableMethod()); 136 137 uint32_t methodOffset1 = 101; 138 MethodLiteral *methodLiteral1 = new MethodLiteral(EntityId(methodOffset1)); 139 JSHandle<Method> method1 = factory->NewSMethod(methodLiteral1); 140 method1->SetIsSendable(true); 141 JSHandle<JSFunction> func1 = factory->NewSFunctionByHClass( 142 method1, JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto())); 143 ASSERT_TRUE(Method::Cast(func1->GetMethod())->IsSendableMethod()); 144} 145} // namespace panda::test 146