• 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     // 1.If Type(O) is not Object, return false.
474     JSTaggedValue obj = GetCallArg(argv, 0).GetTaggedValue();
475     if (!obj.IsHeapObject()) {
476         return GetTaggedBoolean(false);
477     }
478     [[maybe_unused]] EcmaHandleScope handleScope(thread);
479     // 2.Return IsExtensible(O).
480     return GetTaggedBoolean(obj.IsExtensible(thread));
481 }
482 
483 // 19.1.2.12 Object.isFrozen ( O )
IsFrozen(EcmaRuntimeCallInfo * argv)484 JSTaggedValue BuiltinsObject::IsFrozen(EcmaRuntimeCallInfo *argv)
485 {
486     ASSERT(argv);
487     // 1.If Type(O) is not Object, return true.
488     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
489     if (!obj->IsECMAObject()) {
490         return GetTaggedBoolean(true);
491     }
492 
493     JSThread *thread = argv->GetThread();
494     [[maybe_unused]] EcmaHandleScope handleScope(thread);
495 
496     // 2.Return TestIntegrityLevel(O, "frozen").
497     bool status = JSObject::TestIntegrityLevel(thread, JSHandle<JSObject>(obj), IntegrityLevel::FROZEN);
498     return GetTaggedBoolean(status);
499 }
500 
501 // 19.1.2.13 Object.isSealed ( O )
IsSealed(EcmaRuntimeCallInfo * argv)502 JSTaggedValue BuiltinsObject::IsSealed(EcmaRuntimeCallInfo *argv)
503 {
504     ASSERT(argv);
505 
506     // 1.If Type(O) is not Object, return true.
507     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
508     if (!obj->IsECMAObject()) {
509         return GetTaggedBoolean(true);
510     }
511 
512     JSThread *thread = argv->GetThread();
513     [[maybe_unused]] EcmaHandleScope handleScope(thread);
514 
515     // 2.Return TestIntegrityLevel(O, "sealed").
516     bool status = JSObject::TestIntegrityLevel(thread, JSHandle<JSObject>(obj), IntegrityLevel::SEALED);
517     return GetTaggedBoolean(status);
518 }
519 
520 // 19.1.2.14 Object.keys(O)
Keys(EcmaRuntimeCallInfo * argv)521 JSTaggedValue BuiltinsObject::Keys(EcmaRuntimeCallInfo *argv)
522 {
523     ASSERT(argv);
524     JSThread *thread = argv->GetThread();
525     BUILTINS_API_TRACE(thread, Object, Keys);
526     [[maybe_unused]] EcmaHandleScope handleScope(thread);
527 
528     // 1. Let obj be ToObject(O).
529     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
530 
531     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, msg);
532 
533     // 2. ReturnIfAbrupt(obj).
534     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
535 
536     // 3. Let nameList be EnumerableOwnNames(obj).
537     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnNames(thread, obj);
538 
539     // 4. ReturnIfAbrupt(nameList).
540     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
541 
542     // 5. Return CreateArrayFromList(nameList).
543     JSHandle<JSArray> result = JSArray::CreateArrayFromList(thread, nameList);
544     return result.GetTaggedValue();
545 }
546 
547 // 20.1.2.22 Object.values(O)
Values(EcmaRuntimeCallInfo * argv)548 JSTaggedValue BuiltinsObject::Values(EcmaRuntimeCallInfo *argv)
549 {
550     ASSERT(argv);
551     JSThread *thread = argv->GetThread();
552     BUILTINS_API_TRACE(thread, Object, Values);
553     [[maybe_unused]] EcmaHandleScope handleScope(thread);
554 
555     // 1. Let obj be ToObject(O).
556     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
557     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, msg);
558 
559     // 2. ReturnIfAbrupt(obj).
560     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
561 
562     // 3. Let nameList be ? EnumerableOwnPropertyNames(obj, value).
563     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnPropertyNames(thread, obj, PropertyKind::VALUE);
564 
565     // 4. ReturnIfAbrupt(nameList).
566     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
567 
568     // 5. Return CreateArrayFromList(nameList).
569     JSHandle<JSArray> result = JSArray::CreateArrayFromList(thread, nameList);
570     return result.GetTaggedValue();
571 }
572 
573 // 19.1.2.15 Object.preventExtensions(O)
PreventExtensions(EcmaRuntimeCallInfo * argv)574 JSTaggedValue BuiltinsObject::PreventExtensions(EcmaRuntimeCallInfo *argv)
575 {
576     ASSERT(argv);
577     JSThread *thread = argv->GetThread();
578     BUILTINS_API_TRACE(thread, Object, PreventExtensions);
579     // 1. If Type(O) is not Object, return O.
580     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
581     if (!obj->IsECMAObject()) {
582         return obj.GetTaggedValue();
583     }
584     [[maybe_unused]] EcmaHandleScope handleScope(thread);
585     // 2. Let status be O.[[PreventExtensions]]().
586     bool status = JSTaggedValue::PreventExtensions(thread, obj);
587 
588     // 3. ReturnIfAbrupt(status).
589     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
590 
591     // 4. If status is false, throw a TypeError exception.
592     if (!status) {
593         // throw a TypeError exception.
594         THROW_TYPE_ERROR_AND_RETURN(thread, "PreventExtensions: preventExtensions failed",
595                                     JSTaggedValue::Exception());
596     }
597 
598     // 5. Return O.
599     return obj.GetTaggedValue();
600 }
601 // 19.1.2.16 Object.prototype
602 
603 // 19.1.2.17 Object.seal(O)
Seal(EcmaRuntimeCallInfo * argv)604 JSTaggedValue BuiltinsObject::Seal(EcmaRuntimeCallInfo *argv)
605 {
606     ASSERT(argv);
607     JSThread *thread = argv->GetThread();
608     BUILTINS_API_TRACE(thread, Object, Seal);
609 
610     // 1. If Type(O) is not Object, return O.
611     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
612     if (!msg->IsECMAObject()) {
613         return msg.GetTaggedValue();
614     }
615 
616     [[maybe_unused]] EcmaHandleScope handleScope(thread);
617 
618     // 2. Let status be SetIntegrityLevel(O, "sealed").
619     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, msg);
620     bool status = JSObject::SetIntegrityLevel(thread, object, IntegrityLevel::SEALED);
621 
622     // 3. ReturnIfAbrupt(status).
623     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
624 
625     // 4. If status is false, throw a TypeError exception.
626     if (!status) {
627         // throw a TypeError exception.
628         THROW_TYPE_ERROR_AND_RETURN(thread, "Seal: seal failed", JSTaggedValue::Exception());
629     }
630 
631     // 5. Return O.
632     return object.GetTaggedValue();
633 }
634 
635 // 19.1.2.18 Object.setPrototypeOf(O, proto)
SetPrototypeOf(EcmaRuntimeCallInfo * argv)636 JSTaggedValue BuiltinsObject::SetPrototypeOf(EcmaRuntimeCallInfo *argv)
637 {
638     ASSERT(argv);
639     JSThread *thread = argv->GetThread();
640     BUILTINS_API_TRACE(thread, Object, SetPrototypeOf);
641     [[maybe_unused]] EcmaHandleScope handleScope(thread);
642     // 1. Let O be RequireObjectCoercible(O).
643     JSHandle<JSTaggedValue> object = JSTaggedValue::RequireObjectCoercible(thread, GetCallArg(argv, 0));
644 
645     // 2. ReturnIfAbrupt(O).
646     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
647 
648     // 3. If Type(proto) is neither Object nor Null, throw a TypeError exception.
649     JSHandle<JSTaggedValue> proto = GetCallArg(argv, 1);
650     if (!proto->IsNull() && !proto->IsECMAObject()) {
651         // throw a TypeError exception.
652         THROW_TYPE_ERROR_AND_RETURN(thread, "SetPrototypeOf: proto is neither Object nor Null",
653                                     JSTaggedValue::Exception());
654     }
655 
656     // 4. If Type(O) is not Object, return O.
657     if (!object->IsECMAObject()) {
658         return object.GetTaggedValue();
659     }
660 
661     // 5. Let status be O.[[SetPrototypeOf]](proto).
662     bool status = JSTaggedValue::SetPrototype(thread, object, proto);
663 
664     // 6. ReturnIfAbrupt(status).
665     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
666 
667     // 7. If status is false, throw a TypeError exception.
668     if (!status) {
669         // throw a TypeError exception.
670         THROW_TYPE_ERROR_AND_RETURN(thread, "SetPrototypeOf: prototype set failed", JSTaggedValue::Exception());
671     }
672 
673     // 8. Return O.
674     return object.GetTaggedValue();
675 }
676 
677 // 19.1.3.1 Object.prototype.constructor
678 
679 // 19.1.3.2 Object.prototype.hasOwnProperty(V)
HasOwnProperty(EcmaRuntimeCallInfo * argv)680 JSTaggedValue BuiltinsObject::HasOwnProperty(EcmaRuntimeCallInfo *argv)
681 {
682     ASSERT(argv);
683     JSThread *thread = argv->GetThread();
684     BUILTINS_API_TRACE(thread, Object, HasOwnProperty);
685     [[maybe_unused]] EcmaHandleScope handleScope(thread);
686     // 1. Let P be ToPropertyKey(V).
687     JSHandle<JSTaggedValue> prop = GetCallArg(argv, 0);
688     JSHandle<JSTaggedValue> property = JSTaggedValue::ToPropertyKey(thread, prop);
689 
690     // 2. ReturnIfAbrupt(P).
691     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
692 
693     // 3. Let O be ToObject(this value).
694     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
695 
696     // 4. ReturnIfAbrupt(O).
697     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
698 
699     // 5. Return HasOwnProperty(O, P).
700     bool res = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(object), property);
701     return GetTaggedBoolean(res);
702 }
703 
704 // 19.1.3.3 Object.prototype.isPrototypeOf(V)
IsPrototypeOf(EcmaRuntimeCallInfo * argv)705 JSTaggedValue BuiltinsObject::IsPrototypeOf(EcmaRuntimeCallInfo *argv)
706 {
707     ASSERT(argv);
708     JSThread *thread = argv->GetThread();
709     BUILTINS_API_TRACE(thread, Object, IsPrototypeOf);
710     // 1. If Type(V) is not Object, return false.
711     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
712     if (!msg->IsECMAObject()) {
713         return GetTaggedBoolean(false);
714     }
715     [[maybe_unused]] EcmaHandleScope handleScope(thread);
716     // 2. Let O be ToObject(this value).
717     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
718     // 3. ReturnIfAbrupt(O).
719     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
720 
721     // 4. Repeat
722     //    a. Let V be V.[[GetPrototypeOf]]().
723     //    b. If V is null, return false
724     //    c. If SameValue(O, V) is true, return true.
725     JSMutableHandle<JSTaggedValue> msgValueHandle(thread, msg.GetTaggedValue());
726     while (!msgValueHandle->IsNull()) {
727         if (JSTaggedValue::SameValue(object.GetTaggedValue(), msgValueHandle.GetTaggedValue())) {
728             return GetTaggedBoolean(true);
729         }
730         msgValueHandle.Update(JSTaggedValue::GetPrototype(thread, msgValueHandle));
731     }
732     return GetTaggedBoolean(false);
733 }
734 
735 // 19.1.3.4 Object.prototype.propertyIsEnumerable(V)
PropertyIsEnumerable(EcmaRuntimeCallInfo * argv)736 JSTaggedValue BuiltinsObject::PropertyIsEnumerable(EcmaRuntimeCallInfo *argv)
737 {
738     ASSERT(argv);
739     // 1. Let P be ToPropertyKey(V).
740     JSThread *thread = argv->GetThread();
741     [[maybe_unused]] EcmaHandleScope handleScope(thread);
742     JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
743     JSHandle<JSTaggedValue> property = JSTaggedValue::ToPropertyKey(thread, msg);
744 
745     // 2. ReturnIfAbrupt(P).
746     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
747 
748     // 3. Let O be ToObject(this value).
749     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
750     // 4. ReturnIfAbrupt(O).
751     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
752 
753     // 5. Let desc be O.[[GetOwnProperty]](P).
754     PropertyDescriptor desc(thread);
755     JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(object), property, desc);
756 
757     // 6. ReturnIfAbrupt(desc).
758     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
759 
760     // 7. If desc is undefined, return false.
761     if (desc.IsEmpty()) {
762         return GetTaggedBoolean(false);
763     }
764 
765     // 8. Return the value of desc.[[Enumerable]].
766     return GetTaggedBoolean(desc.IsEnumerable());
767 }
768 
769 // 19.1.3.5 Object.prototype.toLocaleString([reserved1[, reserved2]])
ToLocaleString(EcmaRuntimeCallInfo * argv)770 JSTaggedValue BuiltinsObject::ToLocaleString(EcmaRuntimeCallInfo *argv)
771 {
772     ASSERT(argv);
773     JSThread *thread = argv->GetThread();
774     BUILTINS_API_TRACE(thread, Object, ToLocaleString);
775     [[maybe_unused]] EcmaHandleScope handleScope(thread);
776     // 1. Let O be the this value.
777     JSHandle<JSTaggedValue> object = GetThis(argv);
778     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
779 
780     // 2. Return Invoke(O, "toString").
781     JSHandle<JSTaggedValue> calleeKey = thread->GlobalConstants()->GetHandledToStringString();
782     const uint32_t argsLength = argv->GetArgsNumber();
783     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
784     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, object, undefined, argsLength);
785     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
786     info->SetCallArg(argsLength, 0, argv, 0);
787     return JSFunction::Invoke(info, calleeKey);
788 }
789 
GetBuiltinTag(JSThread * thread,const JSHandle<JSObject> & object)790 JSTaggedValue BuiltinsObject::GetBuiltinTag(JSThread *thread, const JSHandle<JSObject> &object)
791 {
792     BUILTINS_API_TRACE(thread, Object, GetBuiltinTag);
793     // 4. Let isArray be IsArray(O).
794     bool isArray = object->IsJSArray();
795     // 5. ReturnIfAbrupt(isArray).
796     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
797 
798     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
799     JSHandle<EcmaString> builtinTag = factory->NewFromASCII("Object");
800     // 6. If isArray is true, let builtinTag be "Array".
801     if (isArray) {
802         builtinTag = factory->NewFromASCII("Array");
803     } else if (object->IsJSPrimitiveRef()) {
804         // 7. Else, if O is an exotic String object, let builtinTag be "String".
805         JSPrimitiveRef *primitiveRef = JSPrimitiveRef::Cast(*object);
806         if (primitiveRef->IsString()) {
807             builtinTag = factory->NewFromASCII("String");
808         } else if (primitiveRef->IsBoolean()) {
809             // 11. Else, if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
810             builtinTag = factory->NewFromASCII("Boolean");
811         } else if (primitiveRef->IsNumber()) {
812             // 12. Else, if O has a [[NumberData]] internal slot, let builtinTag be "Number".
813             builtinTag = factory->NewFromASCII("Number");
814         }
815     } else if (object->IsArguments()) {
816         builtinTag = factory->NewFromASCII("Arguments");
817     } else if (object->IsCallable()) {
818         builtinTag = factory->NewFromASCII("Function");
819     } else if (object->IsJSError()) {
820         builtinTag = JSHandle<EcmaString>::Cast(thread->GlobalConstants()->GetHandledErrorString());
821     } else if (object->IsDate()) {
822         builtinTag = factory->NewFromASCII("Date");
823     } else if (object->IsJSRegExp()) {
824         builtinTag = factory->NewFromASCII("RegExp");
825     }
826     // 15. Else, let builtinTag be "Object".
827     return builtinTag.GetTaggedValue();
828 }
829 
830 // 19.1.3.6 Object.prototype.toString()
ToString(EcmaRuntimeCallInfo * argv)831 JSTaggedValue BuiltinsObject::ToString(EcmaRuntimeCallInfo *argv)
832 {
833     ASSERT(argv);
834     JSThread *thread = argv->GetThread();
835     BUILTINS_API_TRACE(thread, Object, ToString);
836     [[maybe_unused]] EcmaHandleScope handleScope(thread);
837     // 1. If the this value is undefined, return "[object Undefined]".
838 
839     JSHandle<JSTaggedValue> msg = GetThis(argv);
840     if (msg->IsUndefined()) {
841         return GetTaggedString(thread, "[object Undefined]");
842     }
843     // 2. If the this value is null, return "[object Null]".
844     if (msg->IsNull()) {
845         return GetTaggedString(thread, "[object Null]");
846     }
847 
848     // 3. Let O be ToObject(this value).
849     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
850     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
851     JSHandle<JSTaggedValue> builtinTag(thread, GetBuiltinTag(thread, object));
852 
853     // 16. Let tag be Get (O, @@toStringTag).
854     auto ecmaVm = thread->GetEcmaVM();
855     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
856     auto factory = ecmaVm->GetFactory();
857 
858     JSHandle<JSTaggedValue> tag = JSTaggedValue::GetProperty(thread, msg, env->GetToStringTagSymbol()).GetValue();
859 
860     // 17. ReturnIfAbrupt(tag).
861     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
862 
863     // 18. If Type(tag) is not String, let tag be builtinTag.
864     if (!tag->IsString()) {
865         tag = builtinTag;
866     }
867 
868     // 19. Return the String that is the result of concatenating "[object ", tag, and "]".
869     JSHandle<EcmaString> leftString(factory->NewFromASCII("[object "));
870     JSHandle<EcmaString> rightString(factory->NewFromASCII("]"));
871 
872     JSHandle<EcmaString> newLeftStringHandle =
873         factory->ConcatFromString(leftString, JSTaggedValue::ToString(thread, tag));
874     auto result = factory->ConcatFromString(newLeftStringHandle, rightString);
875     return result.GetTaggedValue();
876 }
877 
878 // 19.1.3.7 Object.prototype.valueOf()
ValueOf(EcmaRuntimeCallInfo * argv)879 JSTaggedValue BuiltinsObject::ValueOf(EcmaRuntimeCallInfo *argv)
880 {
881     ASSERT(argv);
882     JSThread *thread = argv->GetThread();
883     BUILTINS_API_TRACE(thread, Object, ValueOf);
884     [[maybe_unused]] EcmaHandleScope handleScope(thread);
885 
886     // 1. Return ToObject(this value).
887     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, GetThis(argv));
888     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
889     return object.GetTaggedValue();
890 }
891 // B.2.2.1 Object.prototype.__proto__
ProtoGetter(EcmaRuntimeCallInfo * argv)892 JSTaggedValue BuiltinsObject::ProtoGetter(EcmaRuntimeCallInfo *argv)
893 {
894     ASSERT(argv);
895     JSThread *thread = argv->GetThread();
896     BUILTINS_API_TRACE(thread, Object, ProtoGetter);
897     [[maybe_unused]] EcmaHandleScope handleScope(thread);
898 
899     // 1.Let obj be ToObject(this value).
900     JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, GetThis(argv));
901 
902     // 2.ReturnIfAbrupt(obj).
903     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
904 
905     // 3.Return obj.[[GetPrototypeOf]]().
906     return JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(obj));
907 }
908 
ProtoSetter(EcmaRuntimeCallInfo * argv)909 JSTaggedValue BuiltinsObject::ProtoSetter(EcmaRuntimeCallInfo *argv)
910 {
911     ASSERT(argv);
912     JSThread *thread = argv->GetThread();
913     BUILTINS_API_TRACE(thread, Object, ProtoSetter);
914     [[maybe_unused]] EcmaHandleScope handleScope(thread);
915     // 1. Let O be RequireObjectCoercible(this value).
916     JSHandle<JSTaggedValue> obj = JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv));
917 
918     // 2. ReturnIfAbrupt(O).
919     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
920 
921     // 3. If Type(proto) is neither Object nor Null, return undefined..
922     JSHandle<JSTaggedValue> proto = GetCallArg(argv, 0);
923     if (!proto->IsNull() && !proto->IsECMAObject()) {
924         return JSTaggedValue::Undefined();
925     }
926 
927     // 4. If Type(O) is not Object, return undefined.
928     if (!obj->IsECMAObject()) {
929         return JSTaggedValue::Undefined();
930     }
931 
932     // 5. Let status be O.[[SetPrototypeOf]](proto).
933     bool status = JSTaggedValue::SetPrototype(thread, obj, proto);
934 
935     // 6. ReturnIfAbrupt(status).
936     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
937 
938     // 7. If status is false, throw a TypeError exception.
939     if (!status) {
940         // throw a TypeError exception.
941         THROW_TYPE_ERROR_AND_RETURN(thread, "ProtoSetter: proto set failed", JSTaggedValue::Exception());
942     }
943 
944     // 8. Return O.
945     return JSTaggedValue::Undefined();
946 }
947 
CreateRealm(EcmaRuntimeCallInfo * argv)948 JSTaggedValue BuiltinsObject::CreateRealm(EcmaRuntimeCallInfo *argv)
949 {
950     ASSERT(argv);
951     JSThread *thread = argv->GetThread();
952     [[maybe_unused]] EcmaHandleScope handleScope(thread);
953     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
954     JSHandle<JSRealm> realm = factory->NewJSRealm();
955     return realm.GetTaggedValue();
956 }
957 
Entries(EcmaRuntimeCallInfo * argv)958 JSTaggedValue BuiltinsObject::Entries(EcmaRuntimeCallInfo *argv)
959 {
960     ASSERT(argv);
961     JSThread *thread = argv->GetThread();
962     BUILTINS_API_TRACE(thread, Object, ToString);
963     [[maybe_unused]] EcmaHandleScope handleScope(thread);
964 
965     // 1. Let obj be ? ToObject(O).
966     JSHandle<JSTaggedValue> obj = GetCallArg(argv, 0);
967     JSHandle<JSObject> object = JSTaggedValue::ToObject(thread, obj);
968     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
969     // 2. Let nameList be ? EnumerableOwnPropertyNames(obj, key+value).
970     JSHandle<TaggedArray> nameList = JSObject::EnumerableOwnPropertyNames(thread, object, PropertyKind::KEY_VALUE);
971     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
972     // 3. Return CreateArrayFromList(nameList).
973     return JSArray::CreateArrayFromList(thread, nameList).GetTaggedValue();
974 }
975 
FromEntries(EcmaRuntimeCallInfo * argv)976 JSTaggedValue BuiltinsObject::FromEntries(EcmaRuntimeCallInfo *argv)
977 {
978     ASSERT(argv);
979     JSThread *thread = argv->GetThread();
980     BUILTINS_API_TRACE(thread, Object, FromEntries);
981     [[maybe_unused]] EcmaHandleScope handleScope(thread);
982 
983     JSHandle<JSTaggedValue> iterable = GetCallArg(argv, 0);
984     // 1. Perform ? RequireObjectCoercible(iterable).
985     if (iterable->IsUndefined() || iterable->IsNull()) {
986         THROW_TYPE_ERROR_AND_RETURN(thread, "iterable is undefined or null", JSTaggedValue::Exception());
987     }
988 
989     // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
990     // 3. Assert: obj is an extensible ordinary object with no own properties.
991     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
992     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
993     JSHandle<JSFunction> constructor(env->GetObjectFunction());
994     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(constructor);
995 
996     // 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions.
997     // 5. Let lengthDefine be the number of non-optional parameters of the function definition in
998     //    CreateDataPropertyOnObject Functions.
999     // 6. Let adder be ! CreateBuiltinFunction(stepsDefine, lengthDefine, "", « »).
1000     JSHandle<Method> method(thread,
1001         thread->GetEcmaVM()->GetMethodByIndex(MethodIndex::BUILTINS_OBJECT_CREATE_DATA_PROPERTY_ON_OBJECT_FUNCTIONS));
1002     JSHandle<JSFunction> addrFunc = factory->NewJSFunction(env, method);
1003 
1004     JSHandle<JSTaggedValue> adder(thread, addrFunc.GetTaggedValue());
1005 
1006     // 7. Return ? AddEntriesFromIterable(obj, iterable, adder).
1007     return BuiltinsMap::AddEntriesFromIterable(thread, obj, iterable, adder, factory);
1008 }
1009 
CreateDataPropertyOnObjectFunctions(EcmaRuntimeCallInfo * argv)1010 JSTaggedValue BuiltinsObject::CreateDataPropertyOnObjectFunctions(EcmaRuntimeCallInfo *argv)
1011 {
1012     ASSERT(argv);
1013     JSThread *thread = argv->GetThread();
1014     BUILTINS_API_TRACE(thread, Object, CreateDataPropertyOnObjectFunctions);
1015     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1016 
1017     // 1. Let O be the this value.
1018     JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1019     JSHandle<JSObject> thisObjHandle = JSHandle<JSObject>::Cast(thisHandle);
1020 
1021     // 2. Assert: Type(O) is Object.
1022     // 3. Assert: O is an extensible ordinary object.
1023     ASSERT(thisHandle->IsHeapObject());
1024 
1025     JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
1026     JSHandle<JSTaggedValue> value = GetCallArg(argv, 1);
1027 
1028     // 4. Let propertyKey be ? ToPropertyKey(key).
1029     JSHandle<JSTaggedValue> propertyKey = JSTaggedValue::ToPropertyKey(thread, key);
1030     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1031 
1032     // 5. Perform ! CreateDataPropertyOrThrow(O, propertyKey, value).
1033     JSObject::CreateDataPropertyOrThrow(thread, thisObjHandle, propertyKey, value);
1034 
1035     // 6. Return undefined.
1036     return JSTaggedValue::Undefined();
1037 }
1038 }  // namespace panda::ecmascript::builtins
1039