14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 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_reflect.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter.h"
194514f5e3Sopenharmony_ci#include "ecmascript/js_object-inl.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins {
224514f5e3Sopenharmony_ci// ecma 26.1.1 Reflect.apply (target, thisArgument, argumentsList)
234514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectApply(EcmaRuntimeCallInfo *argv)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    ASSERT(argv);
264514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, Apply);
274514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
284514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
294514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
304514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> thisArgument = GetCallArg(argv, 1);
314514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> argumentsList = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD);
324514f5e3Sopenharmony_ci    return ReflectApplyInternal(thread, target, thisArgument, argumentsList);
334514f5e3Sopenharmony_ci}
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectApplyInternal(JSThread *thread, JSHandle<JSTaggedValue> target,
364514f5e3Sopenharmony_ci                                                    JSHandle<JSTaggedValue> thisArgument,
374514f5e3Sopenharmony_ci                                                    JSHandle<JSTaggedValue> argumentsList)
384514f5e3Sopenharmony_ci{
394514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
404514f5e3Sopenharmony_ci    // 1. If IsCallable(target) is false, throw a TypeError exception.
414514f5e3Sopenharmony_ci    if (!target->IsCallable()) {
424514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.apply target is not callable", JSTaggedValue::Exception());
434514f5e3Sopenharmony_ci    }
444514f5e3Sopenharmony_ci    // 2. Let args be ? CreateListFromArrayLike(argumentsList).
454514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> argOrAbrupt = JSObject::CreateListFromArrayLike(thread, argumentsList);
464514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
474514f5e3Sopenharmony_ci    JSHandle<TaggedArray> args = JSHandle<TaggedArray>::Cast(argOrAbrupt);
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ci    // 3. Perform PrepareForTailCall().
504514f5e3Sopenharmony_ci    // 4. Return ? Call(target, thisArgument, args).
514514f5e3Sopenharmony_ci    const uint32_t argsLength = args->GetLength();
524514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
534514f5e3Sopenharmony_ci    EcmaRuntimeCallInfo *info =
544514f5e3Sopenharmony_ci        EcmaInterpreter::NewRuntimeCallInfo(thread, target, thisArgument, undefined, argsLength);
554514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
564514f5e3Sopenharmony_ci    info->SetCallArg(argsLength, args);
574514f5e3Sopenharmony_ci    return JSFunction::Call(info);
584514f5e3Sopenharmony_ci}
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ci// ecma 26.1.2 Reflect.construct (target, argumentsList [ , newTarget])
614514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectConstruct(EcmaRuntimeCallInfo *argv)
624514f5e3Sopenharmony_ci{
634514f5e3Sopenharmony_ci    ASSERT(argv);
644514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, Constructor);
654514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
664514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
674514f5e3Sopenharmony_ci    // 1. If IsConstructor(target) is false, throw a TypeError exception.
684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
694514f5e3Sopenharmony_ci    if (!target->IsConstructor()) {
704514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.construct target is not constructor", JSTaggedValue::Exception());
714514f5e3Sopenharmony_ci    }
724514f5e3Sopenharmony_ci    // 2. If newTarget is not present, set newTarget to target.
734514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> newTarget =
744514f5e3Sopenharmony_ci        argv->GetArgsNumber() > 2 ? GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD) : target;  // 2: num args
754514f5e3Sopenharmony_ci    // 3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
764514f5e3Sopenharmony_ci    if (!newTarget->IsConstructor()) {
774514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.construct newTarget is present, but not constructor",
784514f5e3Sopenharmony_ci                                    JSTaggedValue::Exception());
794514f5e3Sopenharmony_ci    }
804514f5e3Sopenharmony_ci    // 4. Let args be ? CreateListFromArrayLike(argumentsList).
814514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> argumentsList = GetCallArg(argv, 1);
824514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> argOrAbrupt = JSObject::CreateListFromArrayLike(thread, argumentsList);
834514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
844514f5e3Sopenharmony_ci    JSHandle<TaggedArray> args = JSHandle<TaggedArray>::Cast(argOrAbrupt);
854514f5e3Sopenharmony_ci    return ReflectConstructInternal(thread, target, args, newTarget);
864514f5e3Sopenharmony_ci}
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectConstructInternal(JSThread *thread, JSHandle<JSTaggedValue> target,
894514f5e3Sopenharmony_ci                                                        JSHandle<TaggedArray> args, JSHandle<JSTaggedValue> newTarget)
904514f5e3Sopenharmony_ci{
914514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
924514f5e3Sopenharmony_ci    // 5. Return ? Construct(target, args, newTarget).
934514f5e3Sopenharmony_ci    const uint32_t argsLength = args->GetLength();
944514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
954514f5e3Sopenharmony_ci    EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, target, undefined, newTarget, argsLength);
964514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
974514f5e3Sopenharmony_ci    info->SetCallArg(argsLength, args);
984514f5e3Sopenharmony_ci    return JSFunction::Construct(info);
994514f5e3Sopenharmony_ci}
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ci// ecma 26.1.3 Reflect.defineProperty (target, propertyKey, attributes)
1024514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectDefineProperty(EcmaRuntimeCallInfo *argv)
1034514f5e3Sopenharmony_ci{
1044514f5e3Sopenharmony_ci    ASSERT(argv);
1054514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, DefineProperty);
1064514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1074514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1084514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
1094514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
1104514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
1114514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.defineProperty target is not object", JSTaggedValue::Exception());
1124514f5e3Sopenharmony_ci    }
1134514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
1144514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, GetCallArg(argv, 1));
1154514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1164514f5e3Sopenharmony_ci    // 3. Let desc be ? ToPropertyDescriptor(attributes).
1174514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> attributes = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD);
1184514f5e3Sopenharmony_ci    PropertyDescriptor desc(thread);
1194514f5e3Sopenharmony_ci    JSObject::ToPropertyDescriptor(thread, attributes, desc);
1204514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1214514f5e3Sopenharmony_ci    // 4. Return ? target.[[DefineOwnProperty]](key, desc).
1224514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::DefineOwnProperty(thread, target, key, desc));
1234514f5e3Sopenharmony_ci}
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_ci// ecma 21.1.4 Reflect.deleteProperty (target, propertyKey)
1264514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectDeleteProperty(EcmaRuntimeCallInfo *argv)
1274514f5e3Sopenharmony_ci{
1284514f5e3Sopenharmony_ci    ASSERT(argv);
1294514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, DeleteProperty);
1304514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1314514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1324514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
1334514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
1344514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
1354514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.deleteProperty target is not object", JSTaggedValue::Exception());
1364514f5e3Sopenharmony_ci    }
1374514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
1384514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, GetCallArg(argv, 1));
1394514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1404514f5e3Sopenharmony_ci    // 3. Return ? target.[[Delete]](key).
1414514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::DeleteProperty(thread, target, key));
1424514f5e3Sopenharmony_ci}
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ci// ecma 26.1.5 Reflect.get (target, propertyKey [ , receiver])
1454514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectGet(EcmaRuntimeCallInfo *argv)
1464514f5e3Sopenharmony_ci{
1474514f5e3Sopenharmony_ci    ASSERT(argv);
1484514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, Get);
1494514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1504514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1514514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
1524514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> val = GetCallArg(argv, 0);
1534514f5e3Sopenharmony_ci    if (!val->IsECMAObject()) {
1544514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.get target is not object", JSTaggedValue::Exception());
1554514f5e3Sopenharmony_ci    }
1564514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
1574514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, GetCallArg(argv, 1));
1584514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1594514f5e3Sopenharmony_ci    // 3. If receiver is not present, then
1604514f5e3Sopenharmony_ci    //     a. Set receiver to target.
1614514f5e3Sopenharmony_ci    // 4. Return ? target.[[Get]](key, receiver).
1624514f5e3Sopenharmony_ci    if (argv->GetArgsNumber() == 2) {  // 2: 2 means that there are 2 args in total
1634514f5e3Sopenharmony_ci        return JSTaggedValue::GetProperty(thread, val, key).GetValue().GetTaggedValue();
1644514f5e3Sopenharmony_ci    }
1654514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> receiver = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD);
1664514f5e3Sopenharmony_ci    return JSTaggedValue::GetProperty(thread, val, key, receiver).GetValue().GetTaggedValue();
1674514f5e3Sopenharmony_ci}
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ci// ecma 26.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )
1704514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectGetOwnPropertyDescriptor(EcmaRuntimeCallInfo *argv)
1714514f5e3Sopenharmony_ci{
1724514f5e3Sopenharmony_ci    ASSERT(argv);
1734514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, GetOwnPropertyDescriptor);
1744514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1754514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1764514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
1774514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
1784514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
1794514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.getOwnPropertyDescriptor target is not object",
1804514f5e3Sopenharmony_ci                                    JSTaggedValue::Exception());
1814514f5e3Sopenharmony_ci    }
1824514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
1834514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, GetCallArg(argv, 1));
1844514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1854514f5e3Sopenharmony_ci    // 3. Let desc be ? target.[[GetOwnProperty]](key).
1864514f5e3Sopenharmony_ci    PropertyDescriptor desc(thread);
1874514f5e3Sopenharmony_ci    if (!JSTaggedValue::GetOwnProperty(thread, target, key, desc)) {
1884514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1894514f5e3Sopenharmony_ci    }
1904514f5e3Sopenharmony_ci    // 4. Return FromPropertyDescriptor(desc).
1914514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> res = JSObject::FromPropertyDescriptor(thread, desc);
1924514f5e3Sopenharmony_ci    return res.GetTaggedValue();
1934514f5e3Sopenharmony_ci}
1944514f5e3Sopenharmony_ci
1954514f5e3Sopenharmony_ci// ecma 21.1.7 Reflect.getPrototypeOf (target)
1964514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectGetPrototypeOf(EcmaRuntimeCallInfo *argv)
1974514f5e3Sopenharmony_ci{
1984514f5e3Sopenharmony_ci    ASSERT(argv);
1994514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, GetPrototypeOf);
2004514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2014514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2024514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2034514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> val = GetCallArg(argv, 0);
2044514f5e3Sopenharmony_ci    if (!val->IsECMAObject()) {
2054514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.getPrototypeOf target is not object", JSTaggedValue::Exception());
2064514f5e3Sopenharmony_ci    }
2074514f5e3Sopenharmony_ci    // 2. Return ? target.[[GetPrototypeOf]]().
2084514f5e3Sopenharmony_ci    return JSTaggedValue::GetPrototype(thread, val);
2094514f5e3Sopenharmony_ci}
2104514f5e3Sopenharmony_ci
2114514f5e3Sopenharmony_ci// ecma 26.1.8 Reflect.has (target, propertyKey)
2124514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectHas(EcmaRuntimeCallInfo *argv)
2134514f5e3Sopenharmony_ci{
2144514f5e3Sopenharmony_ci    ASSERT(argv);
2154514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, Has);
2164514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2174514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2184514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
2194514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = GetCallArg(argv, 1);
2204514f5e3Sopenharmony_ci    return ReflectHasInternal(thread, target, key);
2214514f5e3Sopenharmony_ci}
2224514f5e3Sopenharmony_ci
2234514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectHasInternal(JSThread *thread, JSHandle<JSTaggedValue> target,
2244514f5e3Sopenharmony_ci                                                  JSHandle<JSTaggedValue> key)
2254514f5e3Sopenharmony_ci{
2264514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2274514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2284514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
2294514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.has target is not object", JSTaggedValue::Exception());
2304514f5e3Sopenharmony_ci    }
2314514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
2324514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> propertyKey = JSTaggedValue::ToPropertyKey(thread, key);
2334514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2344514f5e3Sopenharmony_ci    // 3. Return ? target.[[HasProperty]](key).
2354514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::HasProperty(thread, target, propertyKey));
2364514f5e3Sopenharmony_ci}
2374514f5e3Sopenharmony_ci
2384514f5e3Sopenharmony_ci// ecma 26.1.9  Reflect.isExtensible (target)
2394514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectIsExtensible(EcmaRuntimeCallInfo *argv)
2404514f5e3Sopenharmony_ci{
2414514f5e3Sopenharmony_ci    ASSERT(argv);
2424514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2434514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2444514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2454514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
2464514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
2474514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.isExtensible target is not object", JSTaggedValue::Exception());
2484514f5e3Sopenharmony_ci    }
2494514f5e3Sopenharmony_ci    // 2. Return ? target.[[IsExtensible]]().
2504514f5e3Sopenharmony_ci    return GetTaggedBoolean(target->IsExtensible(thread));
2514514f5e3Sopenharmony_ci}
2524514f5e3Sopenharmony_ci
2534514f5e3Sopenharmony_ci// ecma 26.1.10 Reflect.ownKeys (target)
2544514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectOwnKeys(EcmaRuntimeCallInfo *argv)
2554514f5e3Sopenharmony_ci{
2564514f5e3Sopenharmony_ci    ASSERT(argv);
2574514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, OwnKeys);
2584514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2594514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2604514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2614514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
2624514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
2634514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.ownKeys target is not object", JSTaggedValue::Exception());
2644514f5e3Sopenharmony_ci    }
2654514f5e3Sopenharmony_ci    // 2. Let keys be ? target.[[OwnPropertyKeys]]().
2664514f5e3Sopenharmony_ci    JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, target);
2674514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2684514f5e3Sopenharmony_ci    // 3. Return CreateArrayFromList(keys).
2694514f5e3Sopenharmony_ci    JSHandle<JSArray> result = JSArray::CreateArrayFromList(thread, keys);
2704514f5e3Sopenharmony_ci    return result.GetTaggedValue();
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ci// ecma 26.1.11 Reflect.preventExtensions (target)
2744514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectPreventExtensions(EcmaRuntimeCallInfo *argv)
2754514f5e3Sopenharmony_ci{
2764514f5e3Sopenharmony_ci    ASSERT(argv);
2774514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, PreventExtensions);
2784514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2794514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2804514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2814514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
2824514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
2834514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.preventExtensions target is not object",
2844514f5e3Sopenharmony_ci                                    JSTaggedValue::Exception());
2854514f5e3Sopenharmony_ci    }
2864514f5e3Sopenharmony_ci    // 2. Return ? target.[[PreventExtensions]]().
2874514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::PreventExtensions(thread, target));
2884514f5e3Sopenharmony_ci}
2894514f5e3Sopenharmony_ci
2904514f5e3Sopenharmony_ci// ecma 26.1.12 Reflect.set (target, propertyKey, V [ , receiver])
2914514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectSet(EcmaRuntimeCallInfo *argv)
2924514f5e3Sopenharmony_ci{
2934514f5e3Sopenharmony_ci    ASSERT(argv);
2944514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, Set);
2954514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2964514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2974514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
2984514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> targetVal = GetCallArg(argv, 0);
2994514f5e3Sopenharmony_ci    if (!targetVal->IsECMAObject()) {
3004514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.set target is not object", JSTaggedValue::Exception());
3014514f5e3Sopenharmony_ci    }
3024514f5e3Sopenharmony_ci    // 2. Let key be ? ToPropertyKey(propertyKey).
3034514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, GetCallArg(argv, 1));
3044514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3054514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD);
3064514f5e3Sopenharmony_ci    // 3. If receiver is not present, then
3074514f5e3Sopenharmony_ci    //     a. Set receiver to target.
3084514f5e3Sopenharmony_ci    // 4. Return ? target.[[Set]](key, receiver).
3094514f5e3Sopenharmony_ci    if (argv->GetArgsNumber() <= BuiltinsBase::ArgsPosition::FOURTH) {
3104514f5e3Sopenharmony_ci        return GetTaggedBoolean(JSTaggedValue::SetProperty(thread, targetVal, key, value));
3114514f5e3Sopenharmony_ci    }
3124514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> receiver = GetCallArg(argv, BuiltinsBase::ArgsPosition::FOURTH);
3134514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::SetProperty(thread, targetVal, key, value, receiver));
3144514f5e3Sopenharmony_ci}
3154514f5e3Sopenharmony_ci
3164514f5e3Sopenharmony_ci// ecma 26.1.13  Reflect.setPrototypeOf (target, proto)
3174514f5e3Sopenharmony_ciJSTaggedValue BuiltinsReflect::ReflectSetPrototypeOf(EcmaRuntimeCallInfo *argv)
3184514f5e3Sopenharmony_ci{
3194514f5e3Sopenharmony_ci    ASSERT(argv);
3204514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Reflect, SetPrototypeOf);
3214514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3224514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3234514f5e3Sopenharmony_ci    // 1. If Type(target) is not Object, throw a TypeError exception.
3244514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
3254514f5e3Sopenharmony_ci    if (!target->IsECMAObject()) {
3264514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Reflect.setPrototypeOf target is not object", JSTaggedValue::Exception());
3274514f5e3Sopenharmony_ci    }
3284514f5e3Sopenharmony_ci    // 2. If Type(proto) is not Object and proto is not null, throw a TypeError exception.
3294514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> proto = GetCallArg(argv, 1);
3304514f5e3Sopenharmony_ci    if (!proto->IsECMAObject() && !proto->IsNull()) {
3314514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "SetPrototypeOf: proto is neither Object nor Null",
3324514f5e3Sopenharmony_ci                                    JSTaggedValue::Exception());
3334514f5e3Sopenharmony_ci    }
3344514f5e3Sopenharmony_ci    // 3. Return ? target.[[SetPrototypeOf]](proto).
3354514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSTaggedValue::SetPrototype(thread, target, proto));
3364514f5e3Sopenharmony_ci}
3374514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::builtins
338