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