• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_object.h"
17 
18 #include "ecmascript/builtins/builtins_map.h"
19 #include "ecmascript/ecma_macros.h"
20 #include "ecmascript/global_env.h"
21 #include "ecmascript/interpreter/interpreter.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/js_function.h"
24 #include "ecmascript/js_handle.h"
25 #include "ecmascript/js_primitive_ref.h"
26 #include "ecmascript/js_realm.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/object_fast_operator-inl.h"
29 
30 namespace panda::ecmascript::builtins {
31 // 19.1.1.1 Object ( [ value ] )
ObjectConstructor(EcmaRuntimeCallInfo * argv)32 JSTaggedValue BuiltinsObject::ObjectConstructor(EcmaRuntimeCallInfo *argv)
33 {
34     ASSERT(argv);
35     JSThread *thread = argv->GetThread();
36     BUILTINS_API_TRACE(thread, Object, Constructor);
37     [[maybe_unused]] EcmaHandleScope handleScope(thread);
38     auto ecmaVm = thread->GetEcmaVM();
39     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
40 
41     // 1.If NewTarget is neither undefined nor the active function, then
42     //    a.Return OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
43     JSHandle<JSTaggedValue> constructor = GetConstructor(argv);
44     JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv);
45     if (!newTarget->IsUndefined() && !(newTarget.GetTaggedValue() == constructor.GetTaggedValue())) {
46         JSHandle<JSObject> obj =
47             ecmaVm->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget);
48         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
49         return obj.GetTaggedValue();
50     }
51 
52     // 2.If value is null, undefined or not supplied, return ObjectCreate(%ObjectPrototype%).
53     JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
54     if (value->IsNull() || value->IsUndefined()) {
55         JSHandle<JSObject> obj = ecmaVm->GetFactory()->OrdinaryNewJSObjectCreate(env->GetObjectFunctionPrototype());
56         return obj.GetTaggedValue();
57     }
58 
59     // 3.Return ToObject(value).
60     return JSTaggedValue::ToObject(thread, value).GetTaggedValue();
61 }
62 
63 // 19.1.2.1 Object.assign ( target, ...sources )
Assign(EcmaRuntimeCallInfo * argv)64 JSTaggedValue BuiltinsObject::Assign(EcmaRuntimeCallInfo *argv)
65 {
66     ASSERT(argv);
67     JSThread *thread = argv->GetThread();
68     BUILTINS_API_TRACE(thread, Object, Assign);
69     [[maybe_unused]] EcmaHandleScope handleScope(thread);
70 
71     uint32_t numArgs = argv->GetArgsNumber();
72     // 1.Let to be ToObject(target).
73     JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
74     JSHandle<JSObject> toAssign = JSTaggedValue::ToObject(thread, target);
75     // 2.ReturnIfAbrupt(to).
76     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
77 
78     // 3.If only one argument was passed, return to.
79     // 4.Let sources be the List of argument values starting with the second argument.
80     // 5.For each element nextSource of sources, in ascending index order
81     //   a.If nextSource is undefined or null, let keys be an empty List.
82     //   b.Else,
83     //     i.Let from be ToObject(nextSource).
84     //     ii.Let keys be from.[[OwnPropertyKeys]]().
85     //     iii.ReturnIfAbrupt(keys).
86     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
87     for (uint32_t i = 1; i < numArgs; i++) {
88         JSHandle<JSTaggedValue> source = GetCallArg(argv, i);
89         if (!source->IsNull() && !source->IsUndefined()) {
90             JSHandle<JSObject> from = JSTaggedValue::ToObject(thread, source);
91             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
92 
93             JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, JSHandle<JSTaggedValue>::Cast(from));
94             // ReturnIfAbrupt(keys)
95             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
96 
97             // c.Repeat for each element nextKey of keys in List order,
98             //    i.Let desc be from.[[GetOwnProperty]](nextKey).
99             //    ii.ReturnIfAbrupt(desc).
100             //    iii.if desc is not undefined and desc.[[Enumerable]] is true, then
101             //      1.Let propValue be Get(from, nextKey).
102             //      2.ReturnIfAbrupt(propValue).
103             //      3.Let status be Set(to, nextKey, propValue, true).
104             //      4.ReturnIfAbrupt(status).
105             uint32_t keysLen = keys->GetLength();
106             for (uint32_t j = 0; j < keysLen; j++) {
107                 PropertyDescriptor desc(thread);
108                 key.Update(keys->Get(j));
109                 bool success = JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(from), key, desc);
110                 // ReturnIfAbrupt(desc)
111                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
112 
113                 if (success && desc.IsEnumerable()) {
114                     JSTaggedValue value = desc.GetValue().GetTaggedValue();
115                     if (value.IsUndefined() || JSHandle<JSTaggedValue>::Cast(from)->IsJSProxy()) {
116                         value = ObjectFastOperator::FastGetPropertyByValue(thread, from.GetTaggedValue(),
117                                                                            key.GetTaggedValue());
118                     }
119                     // ReturnIfAbrupt(prop_value)
120                     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
121 
122                     ObjectFastOperator::FastSetPropertyByValue(thread, toAssign.GetTaggedValue(), key.GetTaggedValue(),
123                                                                value);
124                     //  ReturnIfAbrupt(status)
125                     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
126                 }
127             }
128         }
129     }
130 
131     // 6.Return to.
132     return toAssign.GetTaggedValue();
133 }
134 
135 // Runtime Semantics
ObjectDefineProperties(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop)136 JSTaggedValue BuiltinsObject::ObjectDefineProperties(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
137                                                      const JSHandle<JSTaggedValue> &prop)
138 {
139     BUILTINS_API_TRACE(thread, Object, DefineProperties);
140     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
141     // 1.If Type(O) is not Object, throw a TypeError exception.
142     if (!obj->IsECMAObject()) {
143         // throw a TypeError exception
144         THROW_TYPE_ERROR_AND_RETURN(thread, "is not an object", JSTaggedValue::Exception());
145     }
146 
147     // 2.Let props be ToObject(Properties).
148     JSHandle<JSObject> props = JSTaggedValue::ToObject(thread, prop);
149 
150     // 3.ReturnIfAbrupt(props).
151     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
152 
153     // 4.Let keys be props.[[OwnPropertyKeys]]().
154     JSHandle<TaggedArray> handleKeys = JSTaggedValue::GetOwnPropertyKeys(thread, JSHandle<JSTaggedValue>::Cast(props));
155 
156     // 5.ReturnIfAbrupt(keys).
157     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
158 
159     // 6.Let descriptors be an empty List.
160     // new an empty array and append
161     uint32_t length = handleKeys->GetLength();
162     [[maybe_unused]] JSHandle<TaggedArray> descriptors =
163         factory->NewTaggedArray(2 * length);  // 2: 2 means two element list
164 
165     // 7.Repeat for each element nextKey of keys in List order,
166     //   a.Let propDesc be props.[[GetOwnProperty]](nextKey).
167     //   b.ReturnIfAbrupt(propDesc).
168     //   c.If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
169     //     i.Let descObj be Get( props, nextKey).
170     //     ii.ReturnIfAbrupt(descObj).
171     //     iii.Let desc be ToPropertyDescriptor(descObj).
172     //     iv.ReturnIfAbrupt(desc).
173     //     v.Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
174     JSMutableHandle<JSTaggedValue> handleKey(thread, JSTaggedValue::Undefined());
175     for (uint32_t i = 0; i < length; i++) {
176         PropertyDescriptor propDesc(thread);
177         handleKey.Update(handleKeys->Get(i));
178 
179         bool success = JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(props), handleKey, propDesc);
180         // ReturnIfAbrupt(propDesc)
181         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
182 
183         if (success && propDesc.IsEnumerable()) {
184             JSHandle<JSTaggedValue> descObj =
185                 JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(props), handleKey).GetValue();
186             // ReturnIfAbrupt(descObj)
187             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
188 
189             PropertyDescriptor desc(thread);
190             JSObject::ToPropertyDescriptor(thread, descObj, desc);
191 
192             // ReturnIfAbrupt(desc)
193             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
194 
195             // 8.For each pair from descriptors in list order,
196             //   a.Let P be the first element of pair.
197             //   b.Let desc be the second element of pair.
198             //   c.Let status be DefinePropertyOrThrow(O,P, desc).
199             //   d.ReturnIfAbrupt(status).
200             [[maybe_unused]] bool setSuccess = JSTaggedValue::DefinePropertyOrThrow(thread, obj, handleKey, desc);
201 
202             // ReturnIfAbrupt(status)
203             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
204         }
205     }
206 
207     // 9.Return O.
208     return obj.GetTaggedValue();
209 }
210 
211 // 19.1.2.2 Object.create ( O [ , Properties ] )
Create(EcmaRuntimeCallInfo * argv)212 JSTaggedValue BuiltinsObject::Create(EcmaRuntimeCallInfo *argv)
213 {
214     ASSERT(argv);
215     JSThread *thread = argv->GetThread();
216     BUILTINS_API_TRACE(thread, Object, Create);
217     [[maybe_unused]] EcmaHandleScope handleScope(thread);
218     // 1.If Type(O) is neither Object nor Null, throw a TypeError exception.
219     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
220     if (!obj->IsECMAObject() && !obj->IsNull()) {
221         // throw a TypeError exception
222         THROW_TYPE_ERROR_AND_RETURN(thread, "Create: O is neither Object nor Null", JSTaggedValue::Exception());
223     }
224 
225     JSHandle<JSTaggedValue> properties = GetCallArg(argv, 1);
226 
227     // 2.Let obj be ObjectCreate(O).
228     JSHandle<JSObject> objCreate = thread->GetEcmaVM()->GetFactory()->OrdinaryNewJSObjectCreate(obj);
229 
230     // 3.If the argument Properties is present and not undefined, then
231     //   a.Return ObjectDefineProperties(obj, Properties).
232     if (!properties->IsUndefined()) {
233         return ObjectDefineProperties(thread, JSHandle<JSTaggedValue>::Cast(objCreate), properties);
234     }
235 
236     // 4.Return obj.
237     return objCreate.GetTaggedValue();
238 }
239 
240 // 19.1.2.3 Object.defineProperties ( O, Properties )
DefineProperties(EcmaRuntimeCallInfo * argv)241 JSTaggedValue BuiltinsObject::DefineProperties(EcmaRuntimeCallInfo *argv)
242 {
243     ASSERT(argv);
244     JSThread *thread = argv->GetThread();
245     BUILTINS_API_TRACE(thread, Object, DefineProperties);
246     [[maybe_unused]] EcmaHandleScope handleScope(thread);
247     // 1.Return ObjectDefineProperties(O, Properties).
248     return ObjectDefineProperties(thread, GetCallArg(argv, 0), GetCallArg(argv, 1));
249 }
250 
251 // 19.1.2.4 Object.defineProperty ( O, P, Attributes )
DefineProperty(EcmaRuntimeCallInfo * argv)252 JSTaggedValue BuiltinsObject::DefineProperty(EcmaRuntimeCallInfo *argv)
253 {
254     ASSERT(argv);
255     JSThread *thread = argv->GetThread();
256     BUILTINS_API_TRACE(thread, Object, DefineProperty);
257     [[maybe_unused]] EcmaHandleScope handleScope(thread);
258 
259     // 1.If Type(O) is not Object, throw a TypeError exception.
260     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
261     if (!obj->IsECMAObject()) {
262         // throw a TypeError
263         THROW_TYPE_ERROR_AND_RETURN(thread, "DefineProperty: O is not Object", JSTaggedValue::Exception());
264     }
265 
266     // 2.Let key be ToPropertyKey(P).
267     JSHandle<JSTaggedValue> prop = GetCallArg(argv, 1);
268     JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, prop);
269 
270     // 3.ReturnIfAbrupt(key).
271     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
272     // 4.Let desc be ToPropertyDescriptor(Attributes).
273     PropertyDescriptor desc(thread);
274     JSObject::ToPropertyDescriptor(thread, GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD), desc);
275 
276     // 5.ReturnIfAbrupt(desc).
277     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
278 
279     // 6.Let success be DefinePropertyOrThrow(O,key, desc).
280     [[maybe_unused]] bool success = JSTaggedValue::DefinePropertyOrThrow(thread, obj, key, desc);
281 
282     // 7.ReturnIfAbrupt(success).
283     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
284     // 8.Return O.
285     return obj.GetTaggedValue();
286 }
287 
288 // 19.1.2.5 Object.freeze ( O )
Freeze(EcmaRuntimeCallInfo * argv)289 JSTaggedValue BuiltinsObject::Freeze(EcmaRuntimeCallInfo *argv)
290 {
291     ASSERT(argv);
292     JSThread *thread = argv->GetThread();
293     BUILTINS_API_TRACE(thread, Object, Freeze);
294 
295     // 1.If Type(O) is not Object, return O.
296     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
297     if (!obj->IsECMAObject()) {
298         return obj.GetTaggedValue();
299     }
300 
301     [[maybe_unused]] EcmaHandleScope handleScope(thread);
302 
303     // 2.Let status be SetIntegrityLevel( O, "frozen").
304     bool status = JSObject::SetIntegrityLevel(thread, JSHandle<JSObject>(obj), IntegrityLevel::FROZEN);
305 
306     // 3.ReturnIfAbrupt(status).
307     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
308 
309     // 4.If status is false, throw a TypeError exception.
310     if (!status) {
311         // throw a TypeError exception
312         THROW_TYPE_ERROR_AND_RETURN(thread, "Freeze: freeze failed", JSTaggedValue::Exception());
313     }
314 
315     // 5.Return O.
316     return obj.GetTaggedValue();
317 }
318 
319 // 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
GetOwnPropertyDescriptor(EcmaRuntimeCallInfo * argv)320 JSTaggedValue BuiltinsObject::GetOwnPropertyDescriptor(EcmaRuntimeCallInfo *argv)
321 {
322     ASSERT(argv);
323     JSThread *thread = argv->GetThread();
324     BUILTINS_API_TRACE(thread, Object, GetOwnPropertyDescriptor);
325     [[maybe_unused]] EcmaHandleScope handleScope(thread);
326 
327     // 1.Let obj be ToObject(O).
328     JSHandle<JSTaggedValue> func = GetCallArg(argv, 0);
329     JSHandle<JSObject> handle = JSTaggedValue::ToObject(thread, func);
330 
331     // 2.ReturnIfAbrupt(obj).
332     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
333 
334     // 3.Let key be ToPropertyKey(P).
335     JSHandle<JSTaggedValue> prop = GetCallArg(argv, 1);
336     JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, prop);
337 
338     // 4.ReturnIfAbrupt(key).
339     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
340 
341     // 5.Let desc be obj.[[GetOwnProperty]](key).
342     PropertyDescriptor desc(thread);
343     JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(handle), key, desc);
344 
345     // 6.ReturnIfAbrupt(desc).
346     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
347 
348     // 7.Return FromPropertyDescriptor(desc).
349     JSHandle<JSTaggedValue> res = JSObject::FromPropertyDescriptor(thread, desc);
350     return res.GetTaggedValue();
351 }
352 
353 // Runtime Semantics
GetOwnPropertyKeys(JSThread * thread,const JSHandle<JSTaggedValue> & object,const KeyType & type)354 JSTaggedValue BuiltinsObject::GetOwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &object,
355                                                  const KeyType &type)
356 {
357     BUILTINS_API_TRACE(thread, Object, GetOwnPropertyKeys);
358     // 1.Let obj be ToObject(O).
359     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
360     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, object);
361 
362     // 2.ReturnIfAbrupt(obj).
363     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
364 
365     // 3.Let keys be obj.[[OwnPropertyKeys]]().
366     JSHandle<TaggedArray> handleKeys = JSTaggedValue::GetOwnPropertyKeys(thread, JSHandle<JSTaggedValue>::Cast(obj));
367 
368     // 4.ReturnIfAbrupt(keys).
369     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
370 
371     // 5.Let nameList be a new empty List.
372     // new an empty array and append
373     uint32_t length = handleKeys->GetLength();
374     JSHandle<TaggedArray> nameList = factory->NewTaggedArray(length);
375 
376     // 6.Repeat for each element nextKey of keys in List order,
377     uint32_t copyLength = 0;
378     switch (type) {
379         case KeyType::STRING_TYPE: {
380             for (uint32_t i = 0; i < length; i++) {
381                 JSTaggedValue key = handleKeys->Get(i);
382                 if (key.IsString()) {
383                     nameList->Set(thread, copyLength, key);
384                     copyLength++;
385                 }
386             }
387             break;
388         }
389         case KeyType::SYMBOL_TYPE: {
390             for (uint32_t i = 0; i < length; i++) {
391                 JSTaggedValue key = handleKeys->Get(i);
392                 if (key.IsSymbol()) {
393                     nameList->Set(thread, copyLength, key);
394                     copyLength++;
395                 }
396             }
397             break;
398         }
399         default:
400             break;
401     }
402 
403     // 7.Return CreateArrayFromList(nameList).
404     JSHandle<TaggedArray> resultList = factory->CopyArray(nameList, length, copyLength);
405     JSHandle<JSArray> resultArray = JSArray::CreateArrayFromList(thread, resultList);
406     return resultArray.GetTaggedValue();
407 }
408 
409 // 19.1.2.7 Object.getOwnPropertyNames ( O )
GetOwnPropertyNames(EcmaRuntimeCallInfo * argv)410 JSTaggedValue BuiltinsObject::GetOwnPropertyNames(EcmaRuntimeCallInfo *argv)
411 {
412     ASSERT(argv);
413     JSThread *thread = argv->GetThread();
414     BUILTINS_API_TRACE(thread, Object, GetOwnPropertyNames);
415     [[maybe_unused]] EcmaHandleScope handleScope(thread);
416     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
417     KeyType type = KeyType::STRING_TYPE;
418 
419     // 1.Return GetOwnPropertyKeys(O, String).
420     return GetOwnPropertyKeys(thread, obj, type);
421 }
422 
423 // 19.1.2.8 Object.getOwnPropertySymbols ( O )
GetOwnPropertySymbols(EcmaRuntimeCallInfo * argv)424 JSTaggedValue BuiltinsObject::GetOwnPropertySymbols(EcmaRuntimeCallInfo *argv)
425 {
426     ASSERT(argv);
427     JSThread *thread = argv->GetThread();
428     BUILTINS_API_TRACE(thread, Object, GetOwnPropertySymbols);
429     [[maybe_unused]] EcmaHandleScope handleScope(thread);
430     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
431     KeyType type = KeyType::SYMBOL_TYPE;
432 
433     // 1.Return GetOwnPropertyKeys(O, Symbol).
434     return GetOwnPropertyKeys(thread, obj, type);
435 }
436 
437 // 19.1.2.9 Object.getPrototypeOf ( O )
GetPrototypeOf(EcmaRuntimeCallInfo * argv)438 JSTaggedValue BuiltinsObject::GetPrototypeOf(EcmaRuntimeCallInfo *argv)
439 {
440     ASSERT(argv);
441     JSThread *thread = argv->GetThread();
442     BUILTINS_API_TRACE(thread, Object, GetPrototypeOf);
443     [[maybe_unused]] EcmaHandleScope handleScope(thread);
444 
445     // 1.Let obj be ToObject(O).
446     JSHandle<JSTaggedValue> func = GetCallArg(argv, 0);
447 
448     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, func);
449 
450     // 2.ReturnIfAbrupt(obj).
451     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
452 
453     // 3.Return obj.[[GetPrototypeOf]]().
454     return JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(obj));
455 }
456 
457 // 19.1.2.10 Object.is ( value1, value2 )
Is(EcmaRuntimeCallInfo * argv)458 JSTaggedValue BuiltinsObject::Is(EcmaRuntimeCallInfo *argv)
459 {
460     ASSERT(argv);
461     BUILTINS_API_TRACE(argv->GetThread(), Object, Is);
462 
463     // 1.Return SameValue(value1, value2).
464     bool result = JSTaggedValue::SameValue(GetCallArg(argv, 0), GetCallArg(argv, 1));
465     return GetTaggedBoolean(result);
466 }
467 
468 // 19.1.2.11 Object.isExtensible ( O )
IsExtensible(EcmaRuntimeCallInfo * argv)469 JSTaggedValue BuiltinsObject::IsExtensible(EcmaRuntimeCallInfo *argv)
470 {
471     ASSERT(argv);
472     JSThread *thread = argv->GetThread();
473     BUILTINS_API_TRACE(thread, Object, IsExtensible);
474     // 1.If Type(O) is not Object, return false.
475     JSTaggedValue obj = GetCallArg(argv, 0).GetTaggedValue();
476     if (!obj.IsHeapObject()) {
477         return GetTaggedBoolean(false);
478     }
479     [[maybe_unused]] EcmaHandleScope handleScope(thread);
480     // 2.Return IsExtensible(O).
481     return GetTaggedBoolean(obj.IsExtensible(thread));
482 }
483 
484 // 19.1.2.12 Object.isFrozen ( O )
IsFrozen(EcmaRuntimeCallInfo * argv)485 JSTaggedValue BuiltinsObject::IsFrozen(EcmaRuntimeCallInfo *argv)
486 {
487     ASSERT(argv);
488     BUILTINS_API_TRACE(argv->GetThread(), Object, IsFrozen);
489     // 1.If Type(O) is not Object, return true.
490     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
491     if (!obj->IsECMAObject()) {
492         return GetTaggedBoolean(true);
493     }
494 
495     JSThread *thread = argv->GetThread();
496     [[maybe_unused]] EcmaHandleScope handleScope(thread);
497 
498     // 2.Return TestIntegrityLevel(O, "frozen").
499     bool status = JSObject::TestIntegrityLevel(thread, JSHandle<JSObject>(obj), IntegrityLevel::FROZEN);
500     return GetTaggedBoolean(status);
501 }
502 
503 // 19.1.2.13 Object.isSealed ( O )
IsSealed(EcmaRuntimeCallInfo * argv)504 JSTaggedValue BuiltinsObject::IsSealed(EcmaRuntimeCallInfo *argv)
505 {
506     ASSERT(argv);
507     BUILTINS_API_TRACE(argv->GetThread(), Object, IsSealed);
508     // 1.If Type(O) is not Object, return true.
509     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
510     if (!obj->IsECMAObject()) {
511         return GetTaggedBoolean(true);
512     }
513 
514     JSThread *thread = argv->GetThread();
515     [[maybe_unused]] EcmaHandleScope handleScope(thread);
516 
517     // 2.Return TestIntegrityLevel(O, "sealed").
518     bool status = JSObject::TestIntegrityLevel(thread, JSHandle<JSObject>(obj), IntegrityLevel::SEALED);
519     return GetTaggedBoolean(status);
520 }
521 
522 // 19.1.2.14 Object.keys(O)
Keys(EcmaRuntimeCallInfo * argv)523 JSTaggedValue BuiltinsObject::Keys(EcmaRuntimeCallInfo *argv)
524 {
525     ASSERT(argv);
526     JSThread *thread = argv->GetThread();
527     BUILTINS_API_TRACE(thread, Object, Keys);
528     [[maybe_unused]] EcmaHandleScope handleScope(thread);
529 
530     // 1. Let obj be ToObject(O).
531     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
532 
533     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, msg);
534 
535     // 2. ReturnIfAbrupt(obj).
536     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
537 
538     // 3. Let nameList be EnumerableOwnNames(obj).
539     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnNames(thread, obj);
540 
541     // 4. ReturnIfAbrupt(nameList).
542     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
543 
544     // 5. Return CreateArrayFromList(nameList).
545     JSHandle<JSArray> result = JSArray::CreateArrayFromList(thread, nameList);
546     return result.GetTaggedValue();
547 }
548 
549 // 20.1.2.22 Object.values(O)
Values(EcmaRuntimeCallInfo * argv)550 JSTaggedValue BuiltinsObject::Values(EcmaRuntimeCallInfo *argv)
551 {
552     ASSERT(argv);
553     JSThread *thread = argv->GetThread();
554     BUILTINS_API_TRACE(thread, Object, Values);
555     [[maybe_unused]] EcmaHandleScope handleScope(thread);
556 
557     // 1. Let obj be ToObject(O).
558     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
559     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, msg);
560 
561     // 2. ReturnIfAbrupt(obj).
562     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
563 
564     // 3. Let nameList be ? EnumerableOwnPropertyNames(obj, value).
565     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnPropertyNames(thread, obj, PropertyKind::VALUE);
566 
567     // 4. ReturnIfAbrupt(nameList).
568     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
569 
570     // 5. Return CreateArrayFromList(nameList).
571     JSHandle<JSArray> result = JSArray::CreateArrayFromList(thread, nameList);
572     return result.GetTaggedValue();
573 }
574 
575 // 19.1.2.15 Object.preventExtensions(O)
PreventExtensions(EcmaRuntimeCallInfo * argv)576 JSTaggedValue BuiltinsObject::PreventExtensions(EcmaRuntimeCallInfo *argv)
577 {
578     ASSERT(argv);
579     JSThread *thread = argv->GetThread();
580     BUILTINS_API_TRACE(thread, Object, PreventExtensions);
581     // 1. If Type(O) is not Object, return O.
582     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
583     if (!obj->IsECMAObject()) {
584         return obj.GetTaggedValue();
585     }
586     [[maybe_unused]] EcmaHandleScope handleScope(thread);
587     // 2. Let status be O.[[PreventExtensions]]().
588     bool status = JSTaggedValue::PreventExtensions(thread, obj);
589 
590     // 3. ReturnIfAbrupt(status).
591     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
592 
593     // 4. If status is false, throw a TypeError exception.
594     if (!status) {
595         // throw a TypeError exception.
596         THROW_TYPE_ERROR_AND_RETURN(thread, "PreventExtensions: preventExtensions failed",
597                                     JSTaggedValue::Exception());
598     }
599 
600     // 5. Return O.
601     return obj.GetTaggedValue();
602 }
603 // 19.1.2.16 Object.prototype
604 
605 // 19.1.2.17 Object.seal(O)
Seal(EcmaRuntimeCallInfo * argv)606 JSTaggedValue BuiltinsObject::Seal(EcmaRuntimeCallInfo *argv)
607 {
608     ASSERT(argv);
609     JSThread *thread = argv->GetThread();
610     BUILTINS_API_TRACE(thread, Object, Seal);
611 
612     // 1. If Type(O) is not Object, return O.
613     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
614     if (!msg->IsECMAObject()) {
615         return msg.GetTaggedValue();
616     }
617 
618     [[maybe_unused]] EcmaHandleScope handleScope(thread);
619 
620     // 2. Let status be SetIntegrityLevel(O, "sealed").
621     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, msg);
622     bool status = JSObject::SetIntegrityLevel(thread, object, IntegrityLevel::SEALED);
623 
624     // 3. ReturnIfAbrupt(status).
625     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
626 
627     // 4. If status is false, throw a TypeError exception.
628     if (!status) {
629         // throw a TypeError exception.
630         THROW_TYPE_ERROR_AND_RETURN(thread, "Seal: seal failed", JSTaggedValue::Exception());
631     }
632 
633     // 5. Return O.
634     return object.GetTaggedValue();
635 }
636 
637 // 19.1.2.18 Object.setPrototypeOf(O, proto)
SetPrototypeOf(EcmaRuntimeCallInfo * argv)638 JSTaggedValue BuiltinsObject::SetPrototypeOf(EcmaRuntimeCallInfo *argv)
639 {
640     ASSERT(argv);
641     JSThread *thread = argv->GetThread();
642     BUILTINS_API_TRACE(thread, Object, SetPrototypeOf);
643     [[maybe_unused]] EcmaHandleScope handleScope(thread);
644     // 1. Let O be RequireObjectCoercible(O).
645     JSHandle<JSTaggedValue> object = JSTaggedValue::RequireObjectCoercible(thread, GetCallArg(argv, 0));
646 
647     // 2. ReturnIfAbrupt(O).
648     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
649 
650     // 3. If Type(proto) is neither Object nor Null, throw a TypeError exception.
651     JSHandle<JSTaggedValue> proto = GetCallArg(argv, 1);
652     if (!proto->IsNull() && !proto->IsECMAObject()) {
653         // throw a TypeError exception.
654         THROW_TYPE_ERROR_AND_RETURN(thread, "SetPrototypeOf: proto is neither Object nor Null",
655                                     JSTaggedValue::Exception());
656     }
657 
658     // 4. If Type(O) is not Object, return O.
659     if (!object->IsECMAObject()) {
660         return object.GetTaggedValue();
661     }
662 
663     // 5. Let status be O.[[SetPrototypeOf]](proto).
664     bool status = JSTaggedValue::SetPrototype(thread, object, proto);
665 
666     // 6. ReturnIfAbrupt(status).
667     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
668 
669     // 7. If status is false, throw a TypeError exception.
670     if (!status) {
671         // throw a TypeError exception.
672         THROW_TYPE_ERROR_AND_RETURN(thread, "SetPrototypeOf: prototype set failed", JSTaggedValue::Exception());
673     }
674 
675     // 8. Return O.
676     return object.GetTaggedValue();
677 }
678 
679 // 19.1.3.1 Object.prototype.constructor
680 
681 // 19.1.3.2 Object.prototype.hasOwnProperty(V)
HasOwnProperty(EcmaRuntimeCallInfo * argv)682 JSTaggedValue BuiltinsObject::HasOwnProperty(EcmaRuntimeCallInfo *argv)
683 {
684     ASSERT(argv);
685     JSThread *thread = argv->GetThread();
686     BUILTINS_API_TRACE(thread, Object, HasOwnProperty);
687     [[maybe_unused]] EcmaHandleScope handleScope(thread);
688     // 1. Let P be ToPropertyKey(V).
689     JSHandle<JSTaggedValue> prop = GetCallArg(argv, 0);
690     JSHandle<JSTaggedValue> property = JSTaggedValue::ToPropertyKey(thread, prop);
691 
692     // 2. ReturnIfAbrupt(P).
693     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
694 
695     // 3. Let O be ToObject(this value).
696     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
697 
698     // 4. ReturnIfAbrupt(O).
699     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
700 
701     // 5. Return HasOwnProperty(O, P).
702     bool res = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(object), property);
703     return GetTaggedBoolean(res);
704 }
705 
706 // 19.1.3.3 Object.prototype.isPrototypeOf(V)
IsPrototypeOf(EcmaRuntimeCallInfo * argv)707 JSTaggedValue BuiltinsObject::IsPrototypeOf(EcmaRuntimeCallInfo *argv)
708 {
709     ASSERT(argv);
710     JSThread *thread = argv->GetThread();
711     BUILTINS_API_TRACE(thread, Object, IsPrototypeOf);
712     // 1. If Type(V) is not Object, return false.
713     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
714     if (!msg->IsECMAObject()) {
715         return GetTaggedBoolean(false);
716     }
717     [[maybe_unused]] EcmaHandleScope handleScope(thread);
718     // 2. Let O be ToObject(this value).
719     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
720     // 3. ReturnIfAbrupt(O).
721     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
722 
723     // 4. Repeat
724     //    a. Let V be V.[[GetPrototypeOf]]().
725     //    b. If V is null, return false
726     //    c. If SameValue(O, V) is true, return true.
727     JSMutableHandle<JSTaggedValue> msgValueHandle(thread, msg.GetTaggedValue());
728     while (!msgValueHandle->IsNull()) {
729         if (JSTaggedValue::SameValue(object.GetTaggedValue(), msgValueHandle.GetTaggedValue())) {
730             return GetTaggedBoolean(true);
731         }
732         msgValueHandle.Update(JSTaggedValue::GetPrototype(thread, msgValueHandle));
733         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
734     }
735     return GetTaggedBoolean(false);
736 }
737 
738 // 19.1.3.4 Object.prototype.propertyIsEnumerable(V)
PropertyIsEnumerable(EcmaRuntimeCallInfo * argv)739 JSTaggedValue BuiltinsObject::PropertyIsEnumerable(EcmaRuntimeCallInfo *argv)
740 {
741     ASSERT(argv);
742     // 1. Let P be ToPropertyKey(V).
743     JSThread *thread = argv->GetThread();
744     BUILTINS_API_TRACE(thread, Object, PropertyIsEnumerable);
745     [[maybe_unused]] EcmaHandleScope handleScope(thread);
746     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
747     JSHandle<JSTaggedValue> property = JSTaggedValue::ToPropertyKey(thread, msg);
748 
749     // 2. ReturnIfAbrupt(P).
750     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
751 
752     // 3. Let O be ToObject(this value).
753     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
754     // 4. ReturnIfAbrupt(O).
755     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
756 
757     // 5. Let desc be O.[[GetOwnProperty]](P).
758     PropertyDescriptor desc(thread);
759     JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(object), property, desc);
760 
761     // 6. ReturnIfAbrupt(desc).
762     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
763 
764     // 7. If desc is undefined, return false.
765     if (desc.IsEmpty()) {
766         return GetTaggedBoolean(false);
767     }
768 
769     // 8. Return the value of desc.[[Enumerable]].
770     return GetTaggedBoolean(desc.IsEnumerable());
771 }
772 
773 // 19.1.3.5 Object.prototype.toLocaleString([reserved1[, reserved2]])
ToLocaleString(EcmaRuntimeCallInfo * argv)774 JSTaggedValue BuiltinsObject::ToLocaleString(EcmaRuntimeCallInfo *argv)
775 {
776     ASSERT(argv);
777     JSThread *thread = argv->GetThread();
778     BUILTINS_API_TRACE(thread, Object, ToLocaleString);
779     [[maybe_unused]] EcmaHandleScope handleScope(thread);
780     // 1. Let O be the this value.
781     JSHandle<JSTaggedValue> object = GetThis(argv);
782     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
783 
784     // 2. Return Invoke(O, "toString").
785     JSHandle<JSTaggedValue> calleeKey = thread->GlobalConstants()->GetHandledToStringString();
786     const uint32_t argsLength = argv->GetArgsNumber();
787     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
788     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, object, undefined, argsLength);
789     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
790     info->SetCallArg(argsLength, 0, argv, 0);
791     return JSFunction::Invoke(info, calleeKey);
792 }
793 
GetBuiltinTag(JSThread * thread,const JSHandle<JSObject> & object)794 JSTaggedValue BuiltinsObject::GetBuiltinTag(JSThread *thread, const JSHandle<JSObject> &object)
795 {
796     BUILTINS_API_TRACE(thread, Object, GetBuiltinTag);
797     // 4. Let isArray be IsArray(O).
798     bool isArray = object->IsJSArray();
799     // 5. ReturnIfAbrupt(isArray).
800     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
801 
802     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
803     JSHandle<EcmaString> builtinTag = factory->NewFromASCII("Object");
804     // 6. If isArray is true, let builtinTag be "Array".
805     if (isArray) {
806         builtinTag = factory->NewFromASCII("Array");
807     } else if (object->IsJSPrimitiveRef()) {
808         // 7. Else, if O is an exotic String object, let builtinTag be "String".
809         JSPrimitiveRef *primitiveRef = JSPrimitiveRef::Cast(*object);
810         if (primitiveRef->IsString()) {
811             builtinTag = factory->NewFromASCII("String");
812         } else if (primitiveRef->IsBoolean()) {
813             // 11. Else, if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
814             builtinTag = factory->NewFromASCII("Boolean");
815         } else if (primitiveRef->IsNumber()) {
816             // 12. Else, if O has a [[NumberData]] internal slot, let builtinTag be "Number".
817             builtinTag = factory->NewFromASCII("Number");
818         }
819     } else if (object->IsArguments()) {
820         builtinTag = factory->NewFromASCII("Arguments");
821     } else if (object->IsCallable()) {
822         builtinTag = factory->NewFromASCII("Function");
823     } else if (object->IsJSError()) {
824         builtinTag = JSHandle<EcmaString>::Cast(thread->GlobalConstants()->GetHandledErrorString());
825     } else if (object->IsDate()) {
826         builtinTag = factory->NewFromASCII("Date");
827     } else if (object->IsJSRegExp()) {
828         builtinTag = factory->NewFromASCII("RegExp");
829     }
830     // 15. Else, let builtinTag be "Object".
831     return builtinTag.GetTaggedValue();
832 }
833 
834 // 19.1.3.6 Object.prototype.toString()
ToString(EcmaRuntimeCallInfo * argv)835 JSTaggedValue BuiltinsObject::ToString(EcmaRuntimeCallInfo *argv)
836 {
837     ASSERT(argv);
838     JSThread *thread = argv->GetThread();
839     BUILTINS_API_TRACE(thread, Object, ToString);
840     [[maybe_unused]] EcmaHandleScope handleScope(thread);
841     // 1. If the this value is undefined, return "[object Undefined]".
842 
843     JSHandle<JSTaggedValue> msg = GetThis(argv);
844     if (msg->IsUndefined()) {
845         return GetTaggedString(thread, "[object Undefined]");
846     }
847     // 2. If the this value is null, return "[object Null]".
848     if (msg->IsNull()) {
849         return GetTaggedString(thread, "[object Null]");
850     }
851 
852     // 3. Let O be ToObject(this value).
853     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
854     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
855     JSHandle<JSTaggedValue> builtinTag(thread, GetBuiltinTag(thread, object));
856 
857     // 16. Let tag be Get (O, @@toStringTag).
858     auto ecmaVm = thread->GetEcmaVM();
859     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
860     auto factory = ecmaVm->GetFactory();
861 
862     JSHandle<JSTaggedValue> tag = JSTaggedValue::GetProperty(thread, msg, env->GetToStringTagSymbol()).GetValue();
863 
864     // 17. ReturnIfAbrupt(tag).
865     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
866 
867     // 18. If Type(tag) is not String, let tag be builtinTag.
868     if (!tag->IsString()) {
869         tag = builtinTag;
870     }
871 
872     // 19. Return the String that is the result of concatenating "[object ", tag, and "]".
873     JSHandle<EcmaString> leftString(factory->NewFromASCII("[object "));
874     JSHandle<EcmaString> rightString(factory->NewFromASCII("]"));
875 
876     JSHandle<EcmaString> newLeftStringHandle =
877         factory->ConcatFromString(leftString, JSTaggedValue::ToString(thread, tag));
878     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
879     auto result = factory->ConcatFromString(newLeftStringHandle, rightString);
880     return result.GetTaggedValue();
881 }
882 
883 // 19.1.3.7 Object.prototype.valueOf()
ValueOf(EcmaRuntimeCallInfo * argv)884 JSTaggedValue BuiltinsObject::ValueOf(EcmaRuntimeCallInfo *argv)
885 {
886     ASSERT(argv);
887     JSThread *thread = argv->GetThread();
888     BUILTINS_API_TRACE(thread, Object, ValueOf);
889     [[maybe_unused]] EcmaHandleScope handleScope(thread);
890 
891     // 1. Return ToObject(this value).
892     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
893     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
894     return object.GetTaggedValue();
895 }
896 // B.2.2.1 Object.prototype.__proto__
ProtoGetter(EcmaRuntimeCallInfo * argv)897 JSTaggedValue BuiltinsObject::ProtoGetter(EcmaRuntimeCallInfo *argv)
898 {
899     ASSERT(argv);
900     JSThread *thread = argv->GetThread();
901     BUILTINS_API_TRACE(thread, Object, ProtoGetter);
902     [[maybe_unused]] EcmaHandleScope handleScope(thread);
903 
904     // 1.Let obj be ToObject(this value).
905     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, GetThis(argv));
906 
907     // 2.ReturnIfAbrupt(obj).
908     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
909 
910     // 3.Return obj.[[GetPrototypeOf]]().
911     return JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(obj));
912 }
913 
ProtoSetter(EcmaRuntimeCallInfo * argv)914 JSTaggedValue BuiltinsObject::ProtoSetter(EcmaRuntimeCallInfo *argv)
915 {
916     ASSERT(argv);
917     JSThread *thread = argv->GetThread();
918     BUILTINS_API_TRACE(thread, Object, ProtoSetter);
919     [[maybe_unused]] EcmaHandleScope handleScope(thread);
920     // 1. Let O be RequireObjectCoercible(this value).
921     JSHandle<JSTaggedValue> obj = JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv));
922 
923     // 2. ReturnIfAbrupt(O).
924     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
925 
926     // 3. If Type(proto) is neither Object nor Null, return undefined..
927     JSHandle<JSTaggedValue> proto = GetCallArg(argv, 0);
928     if (!proto->IsNull() && !proto->IsECMAObject()) {
929         return JSTaggedValue::Undefined();
930     }
931 
932     // 4. If Type(O) is not Object, return undefined.
933     if (!obj->IsECMAObject()) {
934         return JSTaggedValue::Undefined();
935     }
936 
937     // 5. Let status be O.[[SetPrototypeOf]](proto).
938     bool status = JSTaggedValue::SetPrototype(thread, obj, proto);
939 
940     // 6. ReturnIfAbrupt(status).
941     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
942 
943     // 7. If status is false, throw a TypeError exception.
944     if (!status) {
945         // throw a TypeError exception.
946         THROW_TYPE_ERROR_AND_RETURN(thread, "ProtoSetter: proto set failed", JSTaggedValue::Exception());
947     }
948 
949     // 8. Return O.
950     return JSTaggedValue::Undefined();
951 }
952 
CreateRealm(EcmaRuntimeCallInfo * argv)953 JSTaggedValue BuiltinsObject::CreateRealm(EcmaRuntimeCallInfo *argv)
954 {
955     ASSERT(argv);
956     JSThread *thread = argv->GetThread();
957     BUILTINS_API_TRACE(thread, Object, CreateRealm);
958     [[maybe_unused]] EcmaHandleScope handleScope(thread);
959     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
960     JSHandle<JSRealm> realm = factory->NewJSRealm();
961     return realm.GetTaggedValue();
962 }
963 
Entries(EcmaRuntimeCallInfo * argv)964 JSTaggedValue BuiltinsObject::Entries(EcmaRuntimeCallInfo *argv)
965 {
966     ASSERT(argv);
967     JSThread *thread = argv->GetThread();
968     BUILTINS_API_TRACE(thread, Object, ToString);
969     [[maybe_unused]] EcmaHandleScope handleScope(thread);
970 
971     // 1. Let obj be ? ToObject(O).
972     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
973     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, obj);
974     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
975     // 2. Let nameList be ? EnumerableOwnPropertyNames(obj, key+value).
976     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnPropertyNames(thread, object, PropertyKind::KEY_VALUE);
977     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
978     // 3. Return CreateArrayFromList(nameList).
979     return JSArray::CreateArrayFromList(thread, nameList).GetTaggedValue();
980 }
981 
FromEntries(EcmaRuntimeCallInfo * argv)982 JSTaggedValue BuiltinsObject::FromEntries(EcmaRuntimeCallInfo *argv)
983 {
984     ASSERT(argv);
985     JSThread *thread = argv->GetThread();
986     BUILTINS_API_TRACE(thread, Object, FromEntries);
987     [[maybe_unused]] EcmaHandleScope handleScope(thread);
988 
989     JSHandle<JSTaggedValue> iterable = GetCallArg(argv, 0);
990     // 1. Perform ? RequireObjectCoercible(iterable).
991     if (iterable->IsUndefined() || iterable->IsNull()) {
992         THROW_TYPE_ERROR_AND_RETURN(thread, "iterable is undefined or null", JSTaggedValue::Exception());
993     }
994 
995     // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
996     // 3. Assert: obj is an extensible ordinary object with no own properties.
997     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
998     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
999     JSHandle<JSFunction> constructor(env->GetObjectFunction());
1000     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(constructor);
1001 
1002     // 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions.
1003     // 5. Let lengthDefine be the number of non-optional parameters of the function definition in
1004     //    CreateDataPropertyOnObject Functions.
1005     // 6. Let adder be ! CreateBuiltinFunction(stepsDefine, lengthDefine, "", « »).
1006     JSHandle<Method> method(thread,
1007         thread->GetEcmaVM()->GetMethodByIndex(MethodIndex::BUILTINS_OBJECT_CREATE_DATA_PROPERTY_ON_OBJECT_FUNCTIONS));
1008     JSHandle<JSFunction> addrFunc = factory->NewJSFunction(env, method);
1009 
1010     JSHandle<JSTaggedValue> adder(thread, addrFunc.GetTaggedValue());
1011 
1012     // 7. Return ? AddEntriesFromIterable(obj, iterable, adder).
1013     return BuiltinsMap::AddEntriesFromIterable(thread, obj, iterable, adder, factory);
1014 }
1015 
CreateDataPropertyOnObjectFunctions(EcmaRuntimeCallInfo * argv)1016 JSTaggedValue BuiltinsObject::CreateDataPropertyOnObjectFunctions(EcmaRuntimeCallInfo *argv)
1017 {
1018     ASSERT(argv);
1019     JSThread *thread = argv->GetThread();
1020     BUILTINS_API_TRACE(thread, Object, CreateDataPropertyOnObjectFunctions);
1021     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1022 
1023     // 1. Let O be the this value.
1024     JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1025     JSHandle<JSObject> thisObjHandle = JSHandle<JSObject>::Cast(thisHandle);
1026 
1027     // 2. Assert: Type(O) is Object.
1028     // 3. Assert: O is an extensible ordinary object.
1029     ASSERT(thisHandle->IsHeapObject());
1030 
1031     JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
1032     JSHandle<JSTaggedValue> value = GetCallArg(argv, 1);
1033 
1034     // 4. Let propertyKey be ? ToPropertyKey(key).
1035     JSHandle<JSTaggedValue> propertyKey = JSTaggedValue::ToPropertyKey(thread, key);
1036     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1037 
1038     // 5. Perform ! CreateDataPropertyOrThrow(O, propertyKey, value).
1039     JSObject::CreateDataPropertyOrThrow(thread, thisObjHandle, propertyKey, value);
1040     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1041 
1042     // 6. Return undefined.
1043     return JSTaggedValue::Undefined();
1044 }
1045 
HasOwn(EcmaRuntimeCallInfo * argv)1046 JSTaggedValue BuiltinsObject::HasOwn(EcmaRuntimeCallInfo *argv)
1047 {
1048     ASSERT(argv);
1049     JSThread *thread = argv->GetThread();
1050     BUILTINS_API_TRACE(thread, Object, HasOwn);
1051     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1052 
1053     // 1. Let obj be ? ToObject(O).
1054     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
1055     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, obj);
1056 
1057     // 2.ReturnIfAbrupt(obj).
1058     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1059 
1060     // 3.Let key be ToPropertyKey(P).
1061     JSHandle<JSTaggedValue> prop = GetCallArg(argv, 1);
1062     JSHandle<JSTaggedValue> key = JSTaggedValue::ToPropertyKey(thread, prop);
1063 
1064     // 4. ReturnIfAbrupt(4).
1065     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1066 
1067     // 5. Return HasOwnProperty(O, P).
1068     bool res = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(object), key);
1069     return GetTaggedBoolean(res);
1070 }
1071 }  // namespace panda::ecmascript::builtins
1072