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