11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-gen.h"
61cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
71cb0ef41Sopenharmony_ci#include "src/codegen/code-stub-assembler.h"
81cb0ef41Sopenharmony_ci#include "src/common/globals.h"
91cb0ef41Sopenharmony_ci#include "src/heap/factory-inl.h"
101cb0ef41Sopenharmony_ci#include "src/ic/accessor-assembler.h"
111cb0ef41Sopenharmony_ci#include "src/ic/keyed-store-generic.h"
121cb0ef41Sopenharmony_ci#include "src/objects/js-generator.h"
131cb0ef41Sopenharmony_ci#include "src/objects/js-objects.h"
141cb0ef41Sopenharmony_ci#include "src/objects/property-descriptor-object.h"
151cb0ef41Sopenharmony_ci#include "src/objects/property-details.h"
161cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cinamespace v8 {
191cb0ef41Sopenharmony_cinamespace internal {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
221cb0ef41Sopenharmony_ci// ES6 section 19.1 Object Objects
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciclass ObjectBuiltinsAssembler : public CodeStubAssembler {
251cb0ef41Sopenharmony_ci public:
261cb0ef41Sopenharmony_ci  explicit ObjectBuiltinsAssembler(compiler::CodeAssemblerState* state)
271cb0ef41Sopenharmony_ci      : CodeStubAssembler(state) {}
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci protected:
301cb0ef41Sopenharmony_ci  void ReturnToStringFormat(TNode<Context> context, TNode<String> string);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  // TODO(v8:11167) remove |context| and |object| once OrderedNameDictionary
331cb0ef41Sopenharmony_ci  // supported.
341cb0ef41Sopenharmony_ci  void AddToDictionaryIf(TNode<BoolT> condition, TNode<Context> context,
351cb0ef41Sopenharmony_ci                         TNode<Object> object,
361cb0ef41Sopenharmony_ci                         TNode<HeapObject> name_dictionary, Handle<Name> name,
371cb0ef41Sopenharmony_ci                         TNode<Object> value, Label* bailout);
381cb0ef41Sopenharmony_ci  TNode<JSObject> FromPropertyDescriptor(TNode<Context> context,
391cb0ef41Sopenharmony_ci                                         TNode<PropertyDescriptorObject> desc);
401cb0ef41Sopenharmony_ci  TNode<JSObject> FromPropertyDetails(TNode<Context> context,
411cb0ef41Sopenharmony_ci                                      TNode<Object> raw_value,
421cb0ef41Sopenharmony_ci                                      TNode<Word32T> details,
431cb0ef41Sopenharmony_ci                                      Label* if_bailout);
441cb0ef41Sopenharmony_ci  TNode<JSObject> ConstructAccessorDescriptor(TNode<Context> context,
451cb0ef41Sopenharmony_ci                                              TNode<Object> getter,
461cb0ef41Sopenharmony_ci                                              TNode<Object> setter,
471cb0ef41Sopenharmony_ci                                              TNode<BoolT> enumerable,
481cb0ef41Sopenharmony_ci                                              TNode<BoolT> configurable);
491cb0ef41Sopenharmony_ci  TNode<JSObject> ConstructDataDescriptor(TNode<Context> context,
501cb0ef41Sopenharmony_ci                                          TNode<Object> value,
511cb0ef41Sopenharmony_ci                                          TNode<BoolT> writable,
521cb0ef41Sopenharmony_ci                                          TNode<BoolT> enumerable,
531cb0ef41Sopenharmony_ci                                          TNode<BoolT> configurable);
541cb0ef41Sopenharmony_ci  TNode<HeapObject> GetAccessorOrUndefined(TNode<HeapObject> accessor,
551cb0ef41Sopenharmony_ci                                           Label* if_bailout);
561cb0ef41Sopenharmony_ci};
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ciclass ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler {
591cb0ef41Sopenharmony_ci public:
601cb0ef41Sopenharmony_ci  explicit ObjectEntriesValuesBuiltinsAssembler(
611cb0ef41Sopenharmony_ci      compiler::CodeAssemblerState* state)
621cb0ef41Sopenharmony_ci      : ObjectBuiltinsAssembler(state) {}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci protected:
651cb0ef41Sopenharmony_ci  enum CollectType { kEntries, kValues };
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  TNode<BoolT> IsPropertyEnumerable(TNode<Uint32T> details);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  TNode<BoolT> IsPropertyKindAccessor(TNode<Uint32T> kind);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  TNode<BoolT> IsPropertyKindData(TNode<Uint32T> kind);
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  TNode<Uint32T> LoadPropertyKind(TNode<Uint32T> details) {
741cb0ef41Sopenharmony_ci    return DecodeWord32<PropertyDetails::KindField>(details);
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  void GetOwnValuesOrEntries(TNode<Context> context, TNode<Object> maybe_object,
781cb0ef41Sopenharmony_ci                             CollectType collect_type);
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  TNode<JSArray> FastGetOwnValuesOrEntries(
811cb0ef41Sopenharmony_ci      TNode<Context> context, TNode<JSObject> object,
821cb0ef41Sopenharmony_ci      Label* if_call_runtime_with_fast_path, Label* if_no_properties,
831cb0ef41Sopenharmony_ci      CollectType collect_type);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  TNode<JSArray> FinalizeValuesOrEntriesJSArray(
861cb0ef41Sopenharmony_ci      TNode<Context> context, TNode<FixedArray> values_or_entries,
871cb0ef41Sopenharmony_ci      TNode<IntPtrT> size, TNode<Map> array_map, Label* if_empty);
881cb0ef41Sopenharmony_ci};
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_civoid ObjectBuiltinsAssembler::ReturnToStringFormat(TNode<Context> context,
911cb0ef41Sopenharmony_ci                                                   TNode<String> string) {
921cb0ef41Sopenharmony_ci  TNode<String> lhs = StringConstant("[object ");
931cb0ef41Sopenharmony_ci  TNode<String> rhs = StringConstant("]");
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE);
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  Return(CallStub(callable, context, CallStub(callable, context, lhs, string),
981cb0ef41Sopenharmony_ci                  rhs));
991cb0ef41Sopenharmony_ci}
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciTNode<JSObject> ObjectBuiltinsAssembler::ConstructAccessorDescriptor(
1021cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<Object> getter, TNode<Object> setter,
1031cb0ef41Sopenharmony_ci    TNode<BoolT> enumerable, TNode<BoolT> configurable) {
1041cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
1051cb0ef41Sopenharmony_ci  TNode<Map> map = CAST(LoadContextElement(
1061cb0ef41Sopenharmony_ci      native_context, Context::ACCESSOR_PROPERTY_DESCRIPTOR_MAP_INDEX));
1071cb0ef41Sopenharmony_ci  TNode<JSObject> js_desc = AllocateJSObjectFromMap(map);
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
1101cb0ef41Sopenharmony_ci      js_desc, JSAccessorPropertyDescriptor::kGetOffset, getter);
1111cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
1121cb0ef41Sopenharmony_ci      js_desc, JSAccessorPropertyDescriptor::kSetOffset, setter);
1131cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
1141cb0ef41Sopenharmony_ci      js_desc, JSAccessorPropertyDescriptor::kEnumerableOffset,
1151cb0ef41Sopenharmony_ci      SelectBooleanConstant(enumerable));
1161cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
1171cb0ef41Sopenharmony_ci      js_desc, JSAccessorPropertyDescriptor::kConfigurableOffset,
1181cb0ef41Sopenharmony_ci      SelectBooleanConstant(configurable));
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  return js_desc;
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ciTNode<JSObject> ObjectBuiltinsAssembler::ConstructDataDescriptor(
1241cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<Object> value, TNode<BoolT> writable,
1251cb0ef41Sopenharmony_ci    TNode<BoolT> enumerable, TNode<BoolT> configurable) {
1261cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
1271cb0ef41Sopenharmony_ci  TNode<Map> map = CAST(LoadContextElement(
1281cb0ef41Sopenharmony_ci      native_context, Context::DATA_PROPERTY_DESCRIPTOR_MAP_INDEX));
1291cb0ef41Sopenharmony_ci  TNode<JSObject> js_desc = AllocateJSObjectFromMap(map);
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(js_desc,
1321cb0ef41Sopenharmony_ci                                 JSDataPropertyDescriptor::kValueOffset, value);
1331cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(js_desc,
1341cb0ef41Sopenharmony_ci                                 JSDataPropertyDescriptor::kWritableOffset,
1351cb0ef41Sopenharmony_ci                                 SelectBooleanConstant(writable));
1361cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(js_desc,
1371cb0ef41Sopenharmony_ci                                 JSDataPropertyDescriptor::kEnumerableOffset,
1381cb0ef41Sopenharmony_ci                                 SelectBooleanConstant(enumerable));
1391cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(js_desc,
1401cb0ef41Sopenharmony_ci                                 JSDataPropertyDescriptor::kConfigurableOffset,
1411cb0ef41Sopenharmony_ci                                 SelectBooleanConstant(configurable));
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  return js_desc;
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciTNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyEnumerable(
1471cb0ef41Sopenharmony_ci    TNode<Uint32T> details) {
1481cb0ef41Sopenharmony_ci  TNode<Uint32T> attributes =
1491cb0ef41Sopenharmony_ci      DecodeWord32<PropertyDetails::AttributesField>(details);
1501cb0ef41Sopenharmony_ci  return IsNotSetWord32(attributes, PropertyAttributes::DONT_ENUM);
1511cb0ef41Sopenharmony_ci}
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ciTNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindAccessor(
1541cb0ef41Sopenharmony_ci    TNode<Uint32T> kind) {
1551cb0ef41Sopenharmony_ci  return Word32Equal(kind,
1561cb0ef41Sopenharmony_ci                     Int32Constant(static_cast<int>(PropertyKind::kAccessor)));
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ciTNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindData(
1601cb0ef41Sopenharmony_ci    TNode<Uint32T> kind) {
1611cb0ef41Sopenharmony_ci  return Word32Equal(kind,
1621cb0ef41Sopenharmony_ci                     Int32Constant(static_cast<int>(PropertyKind::kData)));
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_civoid ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries(
1661cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<Object> maybe_object,
1671cb0ef41Sopenharmony_ci    CollectType collect_type) {
1681cb0ef41Sopenharmony_ci  TNode<JSReceiver> receiver = ToObject_Inline(context, maybe_object);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  Label if_call_runtime_with_fast_path(this, Label::kDeferred),
1711cb0ef41Sopenharmony_ci      if_call_runtime(this, Label::kDeferred),
1721cb0ef41Sopenharmony_ci      if_no_properties(this, Label::kDeferred);
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(receiver);
1751cb0ef41Sopenharmony_ci  GotoIfNot(IsJSObjectMap(map), &if_call_runtime);
1761cb0ef41Sopenharmony_ci  GotoIfMapHasSlowProperties(map, &if_call_runtime);
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci  TNode<JSObject> object = CAST(receiver);
1791cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> elements = LoadElements(object);
1801cb0ef41Sopenharmony_ci  // If the object has elements, we treat it as slow case.
1811cb0ef41Sopenharmony_ci  // So, we go to runtime call.
1821cb0ef41Sopenharmony_ci  GotoIfNot(IsEmptyFixedArray(elements), &if_call_runtime_with_fast_path);
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  TNode<JSArray> result = FastGetOwnValuesOrEntries(
1851cb0ef41Sopenharmony_ci      context, object, &if_call_runtime_with_fast_path, &if_no_properties,
1861cb0ef41Sopenharmony_ci      collect_type);
1871cb0ef41Sopenharmony_ci  Return(result);
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci  BIND(&if_no_properties);
1901cb0ef41Sopenharmony_ci  {
1911cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
1921cb0ef41Sopenharmony_ci    TNode<Map> array_map =
1931cb0ef41Sopenharmony_ci        LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
1941cb0ef41Sopenharmony_ci    TNode<JSArray> empty_array = AllocateJSArray(
1951cb0ef41Sopenharmony_ci        PACKED_ELEMENTS, array_map, IntPtrConstant(0), SmiConstant(0));
1961cb0ef41Sopenharmony_ci    Return(empty_array);
1971cb0ef41Sopenharmony_ci  }
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  BIND(&if_call_runtime_with_fast_path);
2001cb0ef41Sopenharmony_ci  {
2011cb0ef41Sopenharmony_ci    // In slow case, we simply call runtime.
2021cb0ef41Sopenharmony_ci    if (collect_type == CollectType::kEntries) {
2031cb0ef41Sopenharmony_ci      Return(CallRuntime(Runtime::kObjectEntries, context, object));
2041cb0ef41Sopenharmony_ci    } else {
2051cb0ef41Sopenharmony_ci      DCHECK(collect_type == CollectType::kValues);
2061cb0ef41Sopenharmony_ci      Return(CallRuntime(Runtime::kObjectValues, context, object));
2071cb0ef41Sopenharmony_ci    }
2081cb0ef41Sopenharmony_ci  }
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci  BIND(&if_call_runtime);
2111cb0ef41Sopenharmony_ci  {
2121cb0ef41Sopenharmony_ci    // In slow case, we simply call runtime.
2131cb0ef41Sopenharmony_ci    if (collect_type == CollectType::kEntries) {
2141cb0ef41Sopenharmony_ci      Return(
2151cb0ef41Sopenharmony_ci          CallRuntime(Runtime::kObjectEntriesSkipFastPath, context, receiver));
2161cb0ef41Sopenharmony_ci    } else {
2171cb0ef41Sopenharmony_ci      DCHECK(collect_type == CollectType::kValues);
2181cb0ef41Sopenharmony_ci      Return(
2191cb0ef41Sopenharmony_ci          CallRuntime(Runtime::kObjectValuesSkipFastPath, context, receiver));
2201cb0ef41Sopenharmony_ci    }
2211cb0ef41Sopenharmony_ci  }
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciTNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries(
2251cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSObject> object,
2261cb0ef41Sopenharmony_ci    Label* if_call_runtime_with_fast_path, Label* if_no_properties,
2271cb0ef41Sopenharmony_ci    CollectType collect_type) {
2281cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
2291cb0ef41Sopenharmony_ci  TNode<Map> array_map =
2301cb0ef41Sopenharmony_ci      LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
2311cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(object);
2321cb0ef41Sopenharmony_ci  TNode<Uint32T> bit_field3 = LoadMapBitField3(map);
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  Label if_has_enum_cache(this), if_not_has_enum_cache(this),
2351cb0ef41Sopenharmony_ci      collect_entries(this);
2361cb0ef41Sopenharmony_ci  TNode<IntPtrT> object_enum_length =
2371cb0ef41Sopenharmony_ci      Signed(DecodeWordFromWord32<Map::Bits3::EnumLengthBits>(bit_field3));
2381cb0ef41Sopenharmony_ci  TNode<BoolT> has_enum_cache = WordNotEqual(
2391cb0ef41Sopenharmony_ci      object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel));
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci  // In case, we found enum_cache in object,
2421cb0ef41Sopenharmony_ci  // we use it as array_length because it has same size for
2431cb0ef41Sopenharmony_ci  // Object.(entries/values) result array object length.
2441cb0ef41Sopenharmony_ci  // So object_enum_length use less memory space than
2451cb0ef41Sopenharmony_ci  // NumberOfOwnDescriptorsBits value.
2461cb0ef41Sopenharmony_ci  // And in case, if enum_cache_not_found,
2471cb0ef41Sopenharmony_ci  // we call runtime and initialize enum_cache for subsequent call of
2481cb0ef41Sopenharmony_ci  // CSA fast path.
2491cb0ef41Sopenharmony_ci  Branch(has_enum_cache, &if_has_enum_cache, if_call_runtime_with_fast_path);
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  BIND(&if_has_enum_cache);
2521cb0ef41Sopenharmony_ci  {
2531cb0ef41Sopenharmony_ci    GotoIf(WordEqual(object_enum_length, IntPtrConstant(0)), if_no_properties);
2541cb0ef41Sopenharmony_ci    TNode<FixedArray> values_or_entries =
2551cb0ef41Sopenharmony_ci        CAST(AllocateFixedArray(PACKED_ELEMENTS, object_enum_length,
2561cb0ef41Sopenharmony_ci                                AllocationFlag::kAllowLargeObjectAllocation));
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci    // If in case we have enum_cache,
2591cb0ef41Sopenharmony_ci    // we can't detect accessor of object until loop through descriptors.
2601cb0ef41Sopenharmony_ci    // So if object might have accessor,
2611cb0ef41Sopenharmony_ci    // we will remain invalid addresses of FixedArray.
2621cb0ef41Sopenharmony_ci    // Because in that case, we need to jump to runtime call.
2631cb0ef41Sopenharmony_ci    // So the array filled by the-hole even if enum_cache exists.
2641cb0ef41Sopenharmony_ci    FillFixedArrayWithValue(PACKED_ELEMENTS, values_or_entries,
2651cb0ef41Sopenharmony_ci                            IntPtrConstant(0), object_enum_length,
2661cb0ef41Sopenharmony_ci                            RootIndex::kTheHoleValue);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci    TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0));
2691cb0ef41Sopenharmony_ci    TVARIABLE(IntPtrT, var_descriptor_number, IntPtrConstant(0));
2701cb0ef41Sopenharmony_ci    // Let desc be ? O.[[GetOwnProperty]](key).
2711cb0ef41Sopenharmony_ci    TNode<DescriptorArray> descriptors = LoadMapDescriptors(map);
2721cb0ef41Sopenharmony_ci    Label loop(this, {&var_descriptor_number, &var_result_index}),
2731cb0ef41Sopenharmony_ci        after_loop(this), next_descriptor(this);
2741cb0ef41Sopenharmony_ci    Branch(IntPtrEqual(var_descriptor_number.value(), object_enum_length),
2751cb0ef41Sopenharmony_ci           &after_loop, &loop);
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci    // We dont use BuildFastLoop.
2781cb0ef41Sopenharmony_ci    // Instead, we use hand-written loop
2791cb0ef41Sopenharmony_ci    // because of we need to use 'continue' functionality.
2801cb0ef41Sopenharmony_ci    BIND(&loop);
2811cb0ef41Sopenharmony_ci    {
2821cb0ef41Sopenharmony_ci      // Currently, we will not invoke getters,
2831cb0ef41Sopenharmony_ci      // so, map will not be changed.
2841cb0ef41Sopenharmony_ci      CSA_DCHECK(this, TaggedEqual(map, LoadMap(object)));
2851cb0ef41Sopenharmony_ci      TNode<IntPtrT> descriptor_entry = var_descriptor_number.value();
2861cb0ef41Sopenharmony_ci      TNode<Name> next_key =
2871cb0ef41Sopenharmony_ci          LoadKeyByDescriptorEntry(descriptors, descriptor_entry);
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci      // Skip Symbols.
2901cb0ef41Sopenharmony_ci      GotoIf(IsSymbol(next_key), &next_descriptor);
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci      TNode<Uint32T> details =
2931cb0ef41Sopenharmony_ci          LoadDetailsByDescriptorEntry(descriptors, descriptor_entry);
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci      TNode<Uint32T> kind = LoadPropertyKind(details);
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci      // If property is accessor, we escape fast path and call runtime.
2981cb0ef41Sopenharmony_ci      GotoIf(IsPropertyKindAccessor(kind), if_call_runtime_with_fast_path);
2991cb0ef41Sopenharmony_ci      CSA_DCHECK(this, IsPropertyKindData(kind));
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci      // If desc is not undefined and desc.[[Enumerable]] is true, then skip to
3021cb0ef41Sopenharmony_ci      // the next descriptor.
3031cb0ef41Sopenharmony_ci      GotoIfNot(IsPropertyEnumerable(details), &next_descriptor);
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci      TVARIABLE(Object, var_property_value, UndefinedConstant());
3061cb0ef41Sopenharmony_ci      TNode<IntPtrT> descriptor_name_index = ToKeyIndex<DescriptorArray>(
3071cb0ef41Sopenharmony_ci          Unsigned(TruncateIntPtrToInt32(var_descriptor_number.value())));
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci      // Let value be ? Get(O, key).
3101cb0ef41Sopenharmony_ci      LoadPropertyFromFastObject(object, map, descriptors,
3111cb0ef41Sopenharmony_ci                                 descriptor_name_index, details,
3121cb0ef41Sopenharmony_ci                                 &var_property_value);
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci      // If kind is "value", append value to properties.
3151cb0ef41Sopenharmony_ci      TNode<Object> value = var_property_value.value();
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci      if (collect_type == CollectType::kEntries) {
3181cb0ef41Sopenharmony_ci        // Let entry be CreateArrayFromList(« key, value »).
3191cb0ef41Sopenharmony_ci        TNode<JSArray> array;
3201cb0ef41Sopenharmony_ci        TNode<FixedArrayBase> elements;
3211cb0ef41Sopenharmony_ci        std::tie(array, elements) = AllocateUninitializedJSArrayWithElements(
3221cb0ef41Sopenharmony_ci            PACKED_ELEMENTS, array_map, SmiConstant(2), base::nullopt,
3231cb0ef41Sopenharmony_ci            IntPtrConstant(2));
3241cb0ef41Sopenharmony_ci        StoreFixedArrayElement(CAST(elements), 0, next_key, SKIP_WRITE_BARRIER);
3251cb0ef41Sopenharmony_ci        StoreFixedArrayElement(CAST(elements), 1, value, SKIP_WRITE_BARRIER);
3261cb0ef41Sopenharmony_ci        value = array;
3271cb0ef41Sopenharmony_ci      }
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci      StoreFixedArrayElement(values_or_entries, var_result_index.value(),
3301cb0ef41Sopenharmony_ci                             value);
3311cb0ef41Sopenharmony_ci      Increment(&var_result_index);
3321cb0ef41Sopenharmony_ci      Goto(&next_descriptor);
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci      BIND(&next_descriptor);
3351cb0ef41Sopenharmony_ci      {
3361cb0ef41Sopenharmony_ci        Increment(&var_descriptor_number);
3371cb0ef41Sopenharmony_ci        Branch(IntPtrEqual(var_result_index.value(), object_enum_length),
3381cb0ef41Sopenharmony_ci               &after_loop, &loop);
3391cb0ef41Sopenharmony_ci      }
3401cb0ef41Sopenharmony_ci    }
3411cb0ef41Sopenharmony_ci    BIND(&after_loop);
3421cb0ef41Sopenharmony_ci    return FinalizeValuesOrEntriesJSArray(context, values_or_entries,
3431cb0ef41Sopenharmony_ci                                          var_result_index.value(), array_map,
3441cb0ef41Sopenharmony_ci                                          if_no_properties);
3451cb0ef41Sopenharmony_ci  }
3461cb0ef41Sopenharmony_ci}
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ciTNode<JSArray>
3491cb0ef41Sopenharmony_ciObjectEntriesValuesBuiltinsAssembler::FinalizeValuesOrEntriesJSArray(
3501cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<FixedArray> result, TNode<IntPtrT> size,
3511cb0ef41Sopenharmony_ci    TNode<Map> array_map, Label* if_empty) {
3521cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsJSArrayMap(array_map));
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci  GotoIf(IntPtrEqual(size, IntPtrConstant(0)), if_empty);
3551cb0ef41Sopenharmony_ci  TNode<JSArray> array = AllocateJSArray(array_map, result, SmiTag(size));
3561cb0ef41Sopenharmony_ci  return array;
3571cb0ef41Sopenharmony_ci}
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) {
3601cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kReceiver);
3611cb0ef41Sopenharmony_ci  auto key = Parameter<Object>(Descriptor::kKey);
3621cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  Label call_runtime(this), return_true(this), return_false(this),
3651cb0ef41Sopenharmony_ci      to_primitive(this);
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci  // Smi receivers do not have own properties, just perform ToPrimitive on the
3681cb0ef41Sopenharmony_ci  // key.
3691cb0ef41Sopenharmony_ci  Label if_objectisnotsmi(this);
3701cb0ef41Sopenharmony_ci  Branch(TaggedIsSmi(object), &to_primitive, &if_objectisnotsmi);
3711cb0ef41Sopenharmony_ci  BIND(&if_objectisnotsmi);
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci  TNode<HeapObject> heap_object = CAST(object);
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(heap_object);
3761cb0ef41Sopenharmony_ci  TNode<Uint16T> instance_type = LoadMapInstanceType(map);
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  {
3791cb0ef41Sopenharmony_ci    TVARIABLE(IntPtrT, var_index);
3801cb0ef41Sopenharmony_ci    TVARIABLE(Name, var_unique);
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci    Label if_index(this, &var_index), if_unique_name(this),
3831cb0ef41Sopenharmony_ci        if_notunique_name(this);
3841cb0ef41Sopenharmony_ci    TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique,
3851cb0ef41Sopenharmony_ci              &call_runtime, &if_notunique_name);
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci    BIND(&if_unique_name);
3881cb0ef41Sopenharmony_ci    TryHasOwnProperty(heap_object, map, instance_type, var_unique.value(),
3891cb0ef41Sopenharmony_ci                      &return_true, &return_false, &call_runtime);
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci    BIND(&if_index);
3921cb0ef41Sopenharmony_ci    {
3931cb0ef41Sopenharmony_ci      TryLookupElement(heap_object, map, instance_type, var_index.value(),
3941cb0ef41Sopenharmony_ci                       &return_true, &return_false, &return_false,
3951cb0ef41Sopenharmony_ci                       &call_runtime);
3961cb0ef41Sopenharmony_ci    }
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci    BIND(&if_notunique_name);
3991cb0ef41Sopenharmony_ci    {
4001cb0ef41Sopenharmony_ci      Label not_in_string_table(this);
4011cb0ef41Sopenharmony_ci      TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name,
4021cb0ef41Sopenharmony_ci                           &var_unique, &not_in_string_table, &call_runtime);
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ci      BIND(&not_in_string_table);
4051cb0ef41Sopenharmony_ci      {
4061cb0ef41Sopenharmony_ci        // If the string was not found in the string table, then no regular
4071cb0ef41Sopenharmony_ci        // object can have a property with that name, so return |false|.
4081cb0ef41Sopenharmony_ci        // "Special API objects" with interceptors must take the slow path.
4091cb0ef41Sopenharmony_ci        Branch(IsSpecialReceiverInstanceType(instance_type), &call_runtime,
4101cb0ef41Sopenharmony_ci               &return_false);
4111cb0ef41Sopenharmony_ci      }
4121cb0ef41Sopenharmony_ci    }
4131cb0ef41Sopenharmony_ci  }
4141cb0ef41Sopenharmony_ci  BIND(&to_primitive);
4151cb0ef41Sopenharmony_ci  GotoIf(IsNumber(key), &return_false);
4161cb0ef41Sopenharmony_ci  Branch(IsName(CAST(key)), &return_false, &call_runtime);
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci  BIND(&return_true);
4191cb0ef41Sopenharmony_ci  Return(TrueConstant());
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_ci  BIND(&return_false);
4221cb0ef41Sopenharmony_ci  Return(FalseConstant());
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci  BIND(&call_runtime);
4251cb0ef41Sopenharmony_ci  Return(CallRuntime(Runtime::kObjectHasOwnProperty, context, object, key));
4261cb0ef41Sopenharmony_ci}
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci// ES #sec-object.assign
4291cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) {
4301cb0ef41Sopenharmony_ci  TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
4311cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
4321cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
4351cb0ef41Sopenharmony_ci  TNode<Object> target = args.GetOptionalArgumentValue(0);
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci  // 1. Let to be ? ToObject(target).
4381cb0ef41Sopenharmony_ci  TNode<JSReceiver> to = ToObject_Inline(context, target);
4391cb0ef41Sopenharmony_ci
4401cb0ef41Sopenharmony_ci  Label done(this);
4411cb0ef41Sopenharmony_ci  // 2. If only one argument was passed, return to.
4421cb0ef41Sopenharmony_ci  GotoIf(UintPtrLessThanOrEqual(args.GetLengthWithoutReceiver(),
4431cb0ef41Sopenharmony_ci                                IntPtrConstant(1)),
4441cb0ef41Sopenharmony_ci         &done);
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  // 3. Let sources be the List of argument values starting with the
4471cb0ef41Sopenharmony_ci  //    second argument.
4481cb0ef41Sopenharmony_ci  // 4. For each element nextSource of sources, in ascending index order,
4491cb0ef41Sopenharmony_ci  args.ForEach(
4501cb0ef41Sopenharmony_ci      [=](TNode<Object> next_source) {
4511cb0ef41Sopenharmony_ci        CallBuiltin(Builtin::kSetDataProperties, context, to, next_source);
4521cb0ef41Sopenharmony_ci      },
4531cb0ef41Sopenharmony_ci      IntPtrConstant(1));
4541cb0ef41Sopenharmony_ci  Goto(&done);
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  // 5. Return to.
4571cb0ef41Sopenharmony_ci  BIND(&done);
4581cb0ef41Sopenharmony_ci  args.PopAndReturn(to);
4591cb0ef41Sopenharmony_ci}
4601cb0ef41Sopenharmony_ci
4611cb0ef41Sopenharmony_ci// ES #sec-object.keys
4621cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) {
4631cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kObject);
4641cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
4651cb0ef41Sopenharmony_ci
4661cb0ef41Sopenharmony_ci  TVARIABLE(Smi, var_length);
4671cb0ef41Sopenharmony_ci  TVARIABLE(FixedArrayBase, var_elements);
4681cb0ef41Sopenharmony_ci  Label if_empty(this, Label::kDeferred), if_empty_elements(this),
4691cb0ef41Sopenharmony_ci      if_fast(this), if_slow(this, Label::kDeferred), if_join(this);
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_ci  // Check if the {object} has a usable enum cache.
4721cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(object), &if_slow);
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  TNode<Map> object_map = LoadMap(CAST(object));
4751cb0ef41Sopenharmony_ci  TNode<Uint32T> object_bit_field3 = LoadMapBitField3(object_map);
4761cb0ef41Sopenharmony_ci  TNode<UintPtrT> object_enum_length =
4771cb0ef41Sopenharmony_ci      DecodeWordFromWord32<Map::Bits3::EnumLengthBits>(object_bit_field3);
4781cb0ef41Sopenharmony_ci  GotoIf(
4791cb0ef41Sopenharmony_ci      WordEqual(object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)),
4801cb0ef41Sopenharmony_ci      &if_slow);
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ci  // Ensure that the {object} doesn't have any elements.
4831cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsJSObjectMap(object_map));
4841cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> object_elements = LoadElements(CAST(object));
4851cb0ef41Sopenharmony_ci  GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements);
4861cb0ef41Sopenharmony_ci  Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements,
4871cb0ef41Sopenharmony_ci         &if_slow);
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  // Check whether there are enumerable properties.
4901cb0ef41Sopenharmony_ci  BIND(&if_empty_elements);
4911cb0ef41Sopenharmony_ci  Branch(WordEqual(object_enum_length, IntPtrConstant(0)), &if_empty, &if_fast);
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  // TODO(solanes): These if_xxx here and below seem to be quite similar for
4941cb0ef41Sopenharmony_ci  // ObjectKeys and for ObjectGetOwnPropertyNames. In particular, if_fast seem
4951cb0ef41Sopenharmony_ci  // to be the exact same.
4961cb0ef41Sopenharmony_ci  BIND(&if_fast);
4971cb0ef41Sopenharmony_ci  {
4981cb0ef41Sopenharmony_ci    // The {object} has a usable enum cache, use that.
4991cb0ef41Sopenharmony_ci    TNode<DescriptorArray> object_descriptors = LoadMapDescriptors(object_map);
5001cb0ef41Sopenharmony_ci    TNode<EnumCache> object_enum_cache = LoadObjectField<EnumCache>(
5011cb0ef41Sopenharmony_ci        object_descriptors, DescriptorArray::kEnumCacheOffset);
5021cb0ef41Sopenharmony_ci    auto object_enum_keys = LoadObjectField<FixedArrayBase>(
5031cb0ef41Sopenharmony_ci        object_enum_cache, EnumCache::kKeysOffset);
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci    // Allocate a JSArray and copy the elements from the {object_enum_keys}.
5061cb0ef41Sopenharmony_ci    TNode<JSArray> array;
5071cb0ef41Sopenharmony_ci    TNode<FixedArrayBase> elements;
5081cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
5091cb0ef41Sopenharmony_ci    TNode<Map> array_map =
5101cb0ef41Sopenharmony_ci        LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
5111cb0ef41Sopenharmony_ci    TNode<IntPtrT> object_enum_length_intptr = Signed(object_enum_length);
5121cb0ef41Sopenharmony_ci    TNode<Smi> array_length = SmiTag(object_enum_length_intptr);
5131cb0ef41Sopenharmony_ci    std::tie(array, elements) = AllocateUninitializedJSArrayWithElements(
5141cb0ef41Sopenharmony_ci        PACKED_ELEMENTS, array_map, array_length, base::nullopt,
5151cb0ef41Sopenharmony_ci        object_enum_length_intptr);
5161cb0ef41Sopenharmony_ci    CopyFixedArrayElements(PACKED_ELEMENTS, object_enum_keys, elements,
5171cb0ef41Sopenharmony_ci                           object_enum_length_intptr, SKIP_WRITE_BARRIER);
5181cb0ef41Sopenharmony_ci    Return(array);
5191cb0ef41Sopenharmony_ci  }
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci  BIND(&if_empty);
5221cb0ef41Sopenharmony_ci  {
5231cb0ef41Sopenharmony_ci    // The {object} doesn't have any enumerable keys.
5241cb0ef41Sopenharmony_ci    var_length = SmiConstant(0);
5251cb0ef41Sopenharmony_ci    var_elements = EmptyFixedArrayConstant();
5261cb0ef41Sopenharmony_ci    Goto(&if_join);
5271cb0ef41Sopenharmony_ci  }
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  BIND(&if_slow);
5301cb0ef41Sopenharmony_ci  {
5311cb0ef41Sopenharmony_ci    // Let the runtime compute the elements.
5321cb0ef41Sopenharmony_ci    TNode<FixedArray> elements =
5331cb0ef41Sopenharmony_ci        CAST(CallRuntime(Runtime::kObjectKeys, context, object));
5341cb0ef41Sopenharmony_ci    var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset);
5351cb0ef41Sopenharmony_ci    var_elements = elements;
5361cb0ef41Sopenharmony_ci    Goto(&if_join);
5371cb0ef41Sopenharmony_ci  }
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  BIND(&if_join);
5401cb0ef41Sopenharmony_ci  {
5411cb0ef41Sopenharmony_ci    // Wrap the elements into a proper JSArray and return that.
5421cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
5431cb0ef41Sopenharmony_ci    TNode<Map> array_map =
5441cb0ef41Sopenharmony_ci        LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
5451cb0ef41Sopenharmony_ci    TNode<JSArray> array =
5461cb0ef41Sopenharmony_ci        AllocateJSArray(array_map, var_elements.value(), var_length.value());
5471cb0ef41Sopenharmony_ci    Return(array);
5481cb0ef41Sopenharmony_ci  }
5491cb0ef41Sopenharmony_ci}
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci// https://github.com/tc39/proposal-accessible-object-hasownproperty
5521cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectHasOwn, ObjectBuiltinsAssembler) {
5531cb0ef41Sopenharmony_ci  // Object.prototype.hasOwnProperty()
5541cb0ef41Sopenharmony_ci  // 1. Let obj be ? ToObject(O).
5551cb0ef41Sopenharmony_ci  // 2. Let key be ? ToPropertyKey(P).
5561cb0ef41Sopenharmony_ci  // 3. Return ? HasOwnProperty(obj, key).
5571cb0ef41Sopenharmony_ci  //
5581cb0ef41Sopenharmony_ci  // ObjectPrototypeHasOwnProperty has similar semantics with steps 1 and 2
5591cb0ef41Sopenharmony_ci  // swapped. We check if ToObject can fail and delegate the rest of the
5601cb0ef41Sopenharmony_ci  // execution to ObjectPrototypeHasOwnProperty.
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kJSTarget);
5631cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
5641cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kObject);
5651cb0ef41Sopenharmony_ci  auto key = Parameter<Object>(Descriptor::kKey);
5661cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  // ToObject can only fail when object is undefined or null.
5691cb0ef41Sopenharmony_ci  Label undefined_or_null(this), not_undefined_nor_null(this);
5701cb0ef41Sopenharmony_ci  Branch(IsNullOrUndefined(object), &undefined_or_null,
5711cb0ef41Sopenharmony_ci         &not_undefined_nor_null);
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  BIND(&undefined_or_null);
5741cb0ef41Sopenharmony_ci  ThrowTypeError(context, MessageTemplate::kUndefinedOrNullToObject);
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci  BIND(&not_undefined_nor_null);
5771cb0ef41Sopenharmony_ci  Return(CallBuiltin(Builtin::kObjectPrototypeHasOwnProperty, context, target,
5781cb0ef41Sopenharmony_ci                     new_target, JSParameterCount(1), object, key));
5791cb0ef41Sopenharmony_ci}
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci// ES #sec-object.getOwnPropertyNames
5821cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) {
5831cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kObject);
5841cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci  TVARIABLE(Smi, var_length);
5871cb0ef41Sopenharmony_ci  TVARIABLE(FixedArrayBase, var_elements);
5881cb0ef41Sopenharmony_ci  Label if_empty(this, Label::kDeferred), if_empty_elements(this),
5891cb0ef41Sopenharmony_ci      if_fast(this), try_fast(this, Label::kDeferred),
5901cb0ef41Sopenharmony_ci      if_slow(this, Label::kDeferred), if_join(this);
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci  // Take the slow path if the {object} IsCustomElementsReceiverInstanceType or
5931cb0ef41Sopenharmony_ci  // has any elements.
5941cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(object), &if_slow);
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci  TNode<Map> object_map = LoadMap(CAST(object));
5971cb0ef41Sopenharmony_ci  TNode<Uint16T> instance_type = LoadMapInstanceType(object_map);
5981cb0ef41Sopenharmony_ci  GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &if_slow);
5991cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> object_elements = LoadElements(CAST(object));
6001cb0ef41Sopenharmony_ci  GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements);
6011cb0ef41Sopenharmony_ci  Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements,
6021cb0ef41Sopenharmony_ci         &if_slow);
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci  // Check if the {object} has a usable enum cache.
6051cb0ef41Sopenharmony_ci  BIND(&if_empty_elements);
6061cb0ef41Sopenharmony_ci  TNode<Uint32T> object_bit_field3 = LoadMapBitField3(object_map);
6071cb0ef41Sopenharmony_ci  TNode<UintPtrT> object_enum_length =
6081cb0ef41Sopenharmony_ci      DecodeWordFromWord32<Map::Bits3::EnumLengthBits>(object_bit_field3);
6091cb0ef41Sopenharmony_ci  GotoIf(
6101cb0ef41Sopenharmony_ci      WordEqual(object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)),
6111cb0ef41Sopenharmony_ci      &try_fast);
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci  // Check whether all own properties are enumerable.
6141cb0ef41Sopenharmony_ci  TNode<UintPtrT> number_descriptors =
6151cb0ef41Sopenharmony_ci      DecodeWordFromWord32<Map::Bits3::NumberOfOwnDescriptorsBits>(
6161cb0ef41Sopenharmony_ci          object_bit_field3);
6171cb0ef41Sopenharmony_ci  GotoIfNot(WordEqual(object_enum_length, number_descriptors), &if_slow);
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci  // Check whether there are enumerable properties.
6201cb0ef41Sopenharmony_ci  Branch(WordEqual(object_enum_length, IntPtrConstant(0)), &if_empty, &if_fast);
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  // TODO(solanes): These if_xxx here and below seem to be quite similar for
6231cb0ef41Sopenharmony_ci  // ObjectKeys and for ObjectGetOwnPropertyNames. In particular, if_fast seem
6241cb0ef41Sopenharmony_ci  // to be the exact same.
6251cb0ef41Sopenharmony_ci  BIND(&if_fast);
6261cb0ef41Sopenharmony_ci  {
6271cb0ef41Sopenharmony_ci    // The {object} has a usable enum cache and all own properties are
6281cb0ef41Sopenharmony_ci    // enumerable, use that.
6291cb0ef41Sopenharmony_ci    TNode<DescriptorArray> object_descriptors = LoadMapDescriptors(object_map);
6301cb0ef41Sopenharmony_ci    TNode<EnumCache> object_enum_cache = LoadObjectField<EnumCache>(
6311cb0ef41Sopenharmony_ci        object_descriptors, DescriptorArray::kEnumCacheOffset);
6321cb0ef41Sopenharmony_ci    auto object_enum_keys = LoadObjectField<FixedArrayBase>(
6331cb0ef41Sopenharmony_ci        object_enum_cache, EnumCache::kKeysOffset);
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ci    // Allocate a JSArray and copy the elements from the {object_enum_keys}.
6361cb0ef41Sopenharmony_ci    TNode<JSArray> array;
6371cb0ef41Sopenharmony_ci    TNode<FixedArrayBase> elements;
6381cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
6391cb0ef41Sopenharmony_ci    TNode<Map> array_map =
6401cb0ef41Sopenharmony_ci        LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
6411cb0ef41Sopenharmony_ci    TNode<IntPtrT> object_enum_length_intptr = Signed(object_enum_length);
6421cb0ef41Sopenharmony_ci    TNode<Smi> array_length = SmiTag(object_enum_length_intptr);
6431cb0ef41Sopenharmony_ci    std::tie(array, elements) = AllocateUninitializedJSArrayWithElements(
6441cb0ef41Sopenharmony_ci        PACKED_ELEMENTS, array_map, array_length, base::nullopt,
6451cb0ef41Sopenharmony_ci        object_enum_length_intptr);
6461cb0ef41Sopenharmony_ci    CopyFixedArrayElements(PACKED_ELEMENTS, object_enum_keys, elements,
6471cb0ef41Sopenharmony_ci                           object_enum_length_intptr, SKIP_WRITE_BARRIER);
6481cb0ef41Sopenharmony_ci    Return(array);
6491cb0ef41Sopenharmony_ci  }
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ci  BIND(&try_fast);
6521cb0ef41Sopenharmony_ci  {
6531cb0ef41Sopenharmony_ci    // Let the runtime compute the elements and try initializing enum cache.
6541cb0ef41Sopenharmony_ci    TNode<FixedArray> elements = CAST(CallRuntime(
6551cb0ef41Sopenharmony_ci        Runtime::kObjectGetOwnPropertyNamesTryFast, context, object));
6561cb0ef41Sopenharmony_ci    var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset);
6571cb0ef41Sopenharmony_ci    var_elements = elements;
6581cb0ef41Sopenharmony_ci    Goto(&if_join);
6591cb0ef41Sopenharmony_ci  }
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci  BIND(&if_empty);
6621cb0ef41Sopenharmony_ci  {
6631cb0ef41Sopenharmony_ci    // The {object} doesn't have any enumerable keys.
6641cb0ef41Sopenharmony_ci    var_length = SmiConstant(0);
6651cb0ef41Sopenharmony_ci    var_elements = EmptyFixedArrayConstant();
6661cb0ef41Sopenharmony_ci    Goto(&if_join);
6671cb0ef41Sopenharmony_ci  }
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  BIND(&if_slow);
6701cb0ef41Sopenharmony_ci  {
6711cb0ef41Sopenharmony_ci    // Let the runtime compute the elements.
6721cb0ef41Sopenharmony_ci    TNode<FixedArray> elements =
6731cb0ef41Sopenharmony_ci        CAST(CallRuntime(Runtime::kObjectGetOwnPropertyNames, context, object));
6741cb0ef41Sopenharmony_ci    var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset);
6751cb0ef41Sopenharmony_ci    var_elements = elements;
6761cb0ef41Sopenharmony_ci    Goto(&if_join);
6771cb0ef41Sopenharmony_ci  }
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci  BIND(&if_join);
6801cb0ef41Sopenharmony_ci  {
6811cb0ef41Sopenharmony_ci    // Wrap the elements into a proper JSArray and return that.
6821cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
6831cb0ef41Sopenharmony_ci    TNode<Map> array_map =
6841cb0ef41Sopenharmony_ci        LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
6851cb0ef41Sopenharmony_ci    TNode<JSArray> array =
6861cb0ef41Sopenharmony_ci        AllocateJSArray(array_map, var_elements.value(), var_length.value());
6871cb0ef41Sopenharmony_ci    Return(array);
6881cb0ef41Sopenharmony_ci  }
6891cb0ef41Sopenharmony_ci}
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectValues, ObjectEntriesValuesBuiltinsAssembler) {
6921cb0ef41Sopenharmony_ci  auto object = UncheckedParameter<JSObject>(Descriptor::kObject);
6931cb0ef41Sopenharmony_ci  auto context = UncheckedParameter<Context>(Descriptor::kContext);
6941cb0ef41Sopenharmony_ci  GetOwnValuesOrEntries(context, object, CollectType::kValues);
6951cb0ef41Sopenharmony_ci}
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectEntries, ObjectEntriesValuesBuiltinsAssembler) {
6981cb0ef41Sopenharmony_ci  auto object = UncheckedParameter<JSObject>(Descriptor::kObject);
6991cb0ef41Sopenharmony_ci  auto context = UncheckedParameter<Context>(Descriptor::kContext);
7001cb0ef41Sopenharmony_ci  GetOwnValuesOrEntries(context, object, CollectType::kEntries);
7011cb0ef41Sopenharmony_ci}
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci// ES #sec-object.prototype.isprototypeof
7041cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) {
7051cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
7061cb0ef41Sopenharmony_ci  auto value = Parameter<Object>(Descriptor::kValue);
7071cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
7081cb0ef41Sopenharmony_ci  Label if_receiverisnullorundefined(this, Label::kDeferred),
7091cb0ef41Sopenharmony_ci      if_valueisnotreceiver(this, Label::kDeferred);
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ci  // We only check whether {value} is a Smi here, so that the
7121cb0ef41Sopenharmony_ci  // prototype chain walk below can safely access the {value}s
7131cb0ef41Sopenharmony_ci  // map. We don't rule out Primitive {value}s, since all of
7141cb0ef41Sopenharmony_ci  // them have null as their prototype, so the chain walk below
7151cb0ef41Sopenharmony_ci  // immediately aborts and returns false anyways.
7161cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(value), &if_valueisnotreceiver);
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci  {
7191cb0ef41Sopenharmony_ci    TNode<HeapObject> value_heap_object = CAST(value);
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci    // Check if {receiver} is either null or undefined and in that case,
7221cb0ef41Sopenharmony_ci    // invoke the ToObject builtin, which raises the appropriate error.
7231cb0ef41Sopenharmony_ci    // Otherwise we don't need to invoke ToObject, since {receiver} is
7241cb0ef41Sopenharmony_ci    // either already a JSReceiver, in which case ToObject is a no-op,
7251cb0ef41Sopenharmony_ci    // or it's a Primitive and ToObject would allocate a fresh
7261cb0ef41Sopenharmony_ci    // JSPrimitiveWrapper wrapper, which wouldn't be identical to any existing
7271cb0ef41Sopenharmony_ci    // JSReceiver found in the prototype chain of {value}, hence it will return
7281cb0ef41Sopenharmony_ci    // false no matter if we search for the Primitive {receiver} or
7291cb0ef41Sopenharmony_ci    // a newly allocated JSPrimitiveWrapper wrapper for {receiver}.
7301cb0ef41Sopenharmony_ci    GotoIf(IsNull(receiver), &if_receiverisnullorundefined);
7311cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined);
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_ci    // Loop through the prototype chain looking for the {receiver}.
7341cb0ef41Sopenharmony_ci    Return(HasInPrototypeChain(context, value_heap_object, receiver));
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_ci    BIND(&if_receiverisnullorundefined);
7371cb0ef41Sopenharmony_ci    {
7381cb0ef41Sopenharmony_ci      // If {value} is a primitive HeapObject, we need to return
7391cb0ef41Sopenharmony_ci      // false instead of throwing an exception per order of the
7401cb0ef41Sopenharmony_ci      // steps in the specification, so check that first here.
7411cb0ef41Sopenharmony_ci      GotoIfNot(IsJSReceiver(value_heap_object), &if_valueisnotreceiver);
7421cb0ef41Sopenharmony_ci
7431cb0ef41Sopenharmony_ci      // Simulate the ToObject invocation on {receiver}.
7441cb0ef41Sopenharmony_ci      ToObject(context, receiver);
7451cb0ef41Sopenharmony_ci      Unreachable();
7461cb0ef41Sopenharmony_ci    }
7471cb0ef41Sopenharmony_ci  }
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci  BIND(&if_valueisnotreceiver);
7501cb0ef41Sopenharmony_ci  Return(FalseConstant());
7511cb0ef41Sopenharmony_ci}
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) {
7541cb0ef41Sopenharmony_ci  Label checkstringtag(this), if_arguments(this), if_array(this),
7551cb0ef41Sopenharmony_ci      if_boolean(this), if_date(this), if_error(this), if_function(this),
7561cb0ef41Sopenharmony_ci      if_number(this, Label::kDeferred), if_object(this), if_primitive(this),
7571cb0ef41Sopenharmony_ci      if_proxy(this, Label::kDeferred), if_regexp(this), if_string(this),
7581cb0ef41Sopenharmony_ci      if_symbol(this, Label::kDeferred), if_value(this),
7591cb0ef41Sopenharmony_ci      if_bigint(this, Label::kDeferred);
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
7621cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
7631cb0ef41Sopenharmony_ci
7641cb0ef41Sopenharmony_ci  TVARIABLE(String, var_default);
7651cb0ef41Sopenharmony_ci  TVARIABLE(HeapObject, var_holder);
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_ci  // This is arranged to check the likely cases first.
7681cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(receiver), &if_number);
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci  TNode<HeapObject> receiver_heap_object = CAST(receiver);
7711cb0ef41Sopenharmony_ci  TNode<Map> receiver_map = LoadMap(receiver_heap_object);
7721cb0ef41Sopenharmony_ci  var_holder = receiver_heap_object;
7731cb0ef41Sopenharmony_ci  TNode<Uint16T> receiver_instance_type = LoadMapInstanceType(receiver_map);
7741cb0ef41Sopenharmony_ci  GotoIf(IsPrimitiveInstanceType(receiver_instance_type), &if_primitive);
7751cb0ef41Sopenharmony_ci  GotoIf(IsFunctionInstanceType(receiver_instance_type), &if_function);
7761cb0ef41Sopenharmony_ci  const struct {
7771cb0ef41Sopenharmony_ci    InstanceType value;
7781cb0ef41Sopenharmony_ci    Label* label;
7791cb0ef41Sopenharmony_ci  } kJumpTable[] = {{JS_OBJECT_TYPE, &if_object},
7801cb0ef41Sopenharmony_ci                    {JS_ARRAY_TYPE, &if_array},
7811cb0ef41Sopenharmony_ci                    {JS_REG_EXP_TYPE, &if_regexp},
7821cb0ef41Sopenharmony_ci                    {JS_ARGUMENTS_OBJECT_TYPE, &if_arguments},
7831cb0ef41Sopenharmony_ci                    {JS_DATE_TYPE, &if_date},
7841cb0ef41Sopenharmony_ci                    {JS_API_OBJECT_TYPE, &if_object},
7851cb0ef41Sopenharmony_ci                    {JS_SPECIAL_API_OBJECT_TYPE, &if_object},
7861cb0ef41Sopenharmony_ci                    {JS_PROXY_TYPE, &if_proxy},
7871cb0ef41Sopenharmony_ci                    {JS_ERROR_TYPE, &if_error},
7881cb0ef41Sopenharmony_ci                    {JS_PRIMITIVE_WRAPPER_TYPE, &if_value}};
7891cb0ef41Sopenharmony_ci  size_t const kNumCases = arraysize(kJumpTable);
7901cb0ef41Sopenharmony_ci  Label* case_labels[kNumCases];
7911cb0ef41Sopenharmony_ci  int32_t case_values[kNumCases];
7921cb0ef41Sopenharmony_ci  for (size_t i = 0; i < kNumCases; ++i) {
7931cb0ef41Sopenharmony_ci    case_labels[i] = kJumpTable[i].label;
7941cb0ef41Sopenharmony_ci    case_values[i] = kJumpTable[i].value;
7951cb0ef41Sopenharmony_ci  }
7961cb0ef41Sopenharmony_ci  Switch(receiver_instance_type, &if_object, case_values, case_labels,
7971cb0ef41Sopenharmony_ci         arraysize(case_values));
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  BIND(&if_arguments);
8001cb0ef41Sopenharmony_ci  {
8011cb0ef41Sopenharmony_ci    var_default = ArgumentsToStringConstant();
8021cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8031cb0ef41Sopenharmony_ci  }
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ci  BIND(&if_array);
8061cb0ef41Sopenharmony_ci  {
8071cb0ef41Sopenharmony_ci    var_default = ArrayToStringConstant();
8081cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8091cb0ef41Sopenharmony_ci  }
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci  BIND(&if_boolean);
8121cb0ef41Sopenharmony_ci  {
8131cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
8141cb0ef41Sopenharmony_ci    TNode<JSFunction> boolean_constructor = CAST(
8151cb0ef41Sopenharmony_ci        LoadContextElement(native_context, Context::BOOLEAN_FUNCTION_INDEX));
8161cb0ef41Sopenharmony_ci    TNode<Map> boolean_initial_map = LoadObjectField<Map>(
8171cb0ef41Sopenharmony_ci        boolean_constructor, JSFunction::kPrototypeOrInitialMapOffset);
8181cb0ef41Sopenharmony_ci    TNode<HeapObject> boolean_prototype =
8191cb0ef41Sopenharmony_ci        LoadObjectField<HeapObject>(boolean_initial_map, Map::kPrototypeOffset);
8201cb0ef41Sopenharmony_ci    var_default = BooleanToStringConstant();
8211cb0ef41Sopenharmony_ci    var_holder = boolean_prototype;
8221cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8231cb0ef41Sopenharmony_ci  }
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci  BIND(&if_date);
8261cb0ef41Sopenharmony_ci  {
8271cb0ef41Sopenharmony_ci    var_default = DateToStringConstant();
8281cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8291cb0ef41Sopenharmony_ci  }
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci  BIND(&if_error);
8321cb0ef41Sopenharmony_ci  {
8331cb0ef41Sopenharmony_ci    var_default = ErrorToStringConstant();
8341cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8351cb0ef41Sopenharmony_ci  }
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci  BIND(&if_function);
8381cb0ef41Sopenharmony_ci  {
8391cb0ef41Sopenharmony_ci    var_default = FunctionToStringConstant();
8401cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8411cb0ef41Sopenharmony_ci  }
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ci  BIND(&if_number);
8441cb0ef41Sopenharmony_ci  {
8451cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
8461cb0ef41Sopenharmony_ci    TNode<JSFunction> number_constructor = CAST(
8471cb0ef41Sopenharmony_ci        LoadContextElement(native_context, Context::NUMBER_FUNCTION_INDEX));
8481cb0ef41Sopenharmony_ci    TNode<Map> number_initial_map = LoadObjectField<Map>(
8491cb0ef41Sopenharmony_ci        number_constructor, JSFunction::kPrototypeOrInitialMapOffset);
8501cb0ef41Sopenharmony_ci    TNode<HeapObject> number_prototype =
8511cb0ef41Sopenharmony_ci        LoadObjectField<HeapObject>(number_initial_map, Map::kPrototypeOffset);
8521cb0ef41Sopenharmony_ci    var_default = NumberToStringConstant();
8531cb0ef41Sopenharmony_ci    var_holder = number_prototype;
8541cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8551cb0ef41Sopenharmony_ci  }
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci  BIND(&if_object);
8581cb0ef41Sopenharmony_ci  {
8591cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsJSReceiver(CAST(receiver)));
8601cb0ef41Sopenharmony_ci    var_default = ObjectToStringConstant();
8611cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
8621cb0ef41Sopenharmony_ci  }
8631cb0ef41Sopenharmony_ci
8641cb0ef41Sopenharmony_ci  BIND(&if_primitive);
8651cb0ef41Sopenharmony_ci  {
8661cb0ef41Sopenharmony_ci    Label return_undefined(this);
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_ci    GotoIf(IsStringInstanceType(receiver_instance_type), &if_string);
8691cb0ef41Sopenharmony_ci    GotoIf(IsBigIntInstanceType(receiver_instance_type), &if_bigint);
8701cb0ef41Sopenharmony_ci    GotoIf(IsBooleanMap(receiver_map), &if_boolean);
8711cb0ef41Sopenharmony_ci    GotoIf(IsHeapNumberMap(receiver_map), &if_number);
8721cb0ef41Sopenharmony_ci    GotoIf(IsSymbolMap(receiver_map), &if_symbol);
8731cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(receiver), &return_undefined);
8741cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsNull(receiver));
8751cb0ef41Sopenharmony_ci    Return(NullToStringConstant());
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci    BIND(&return_undefined);
8781cb0ef41Sopenharmony_ci    Return(UndefinedToStringConstant());
8791cb0ef41Sopenharmony_ci  }
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ci  BIND(&if_proxy);
8821cb0ef41Sopenharmony_ci  {
8831cb0ef41Sopenharmony_ci    // If {receiver} is a proxy for a JSArray, we default to "[object Array]",
8841cb0ef41Sopenharmony_ci    // otherwise we default to "[object Object]" or "[object Function]" here,
8851cb0ef41Sopenharmony_ci    // depending on whether the {receiver} is callable. The order matters here,
8861cb0ef41Sopenharmony_ci    // i.e. we need to execute the %ArrayIsArray check before the [[Get]] below,
8871cb0ef41Sopenharmony_ci    // as the exception is observable.
8881cb0ef41Sopenharmony_ci    TNode<Object> receiver_is_array =
8891cb0ef41Sopenharmony_ci        CallRuntime(Runtime::kArrayIsArray, context, receiver);
8901cb0ef41Sopenharmony_ci    TNode<String> builtin_tag = Select<String>(
8911cb0ef41Sopenharmony_ci        IsTrue(receiver_is_array), [=] { return ArrayStringConstant(); },
8921cb0ef41Sopenharmony_ci        [=] {
8931cb0ef41Sopenharmony_ci          return Select<String>(
8941cb0ef41Sopenharmony_ci              IsCallableMap(receiver_map),
8951cb0ef41Sopenharmony_ci              [=] { return FunctionStringConstant(); },
8961cb0ef41Sopenharmony_ci              [=] { return ObjectStringConstant(); });
8971cb0ef41Sopenharmony_ci        });
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_ci    // Lookup the @@toStringTag property on the {receiver}.
9001cb0ef41Sopenharmony_ci    TVARIABLE(Object, var_tag,
9011cb0ef41Sopenharmony_ci              GetProperty(context, receiver,
9021cb0ef41Sopenharmony_ci                          isolate()->factory()->to_string_tag_symbol()));
9031cb0ef41Sopenharmony_ci    Label if_tagisnotstring(this), if_tagisstring(this);
9041cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(var_tag.value()), &if_tagisnotstring);
9051cb0ef41Sopenharmony_ci    Branch(IsString(CAST(var_tag.value())), &if_tagisstring,
9061cb0ef41Sopenharmony_ci           &if_tagisnotstring);
9071cb0ef41Sopenharmony_ci    BIND(&if_tagisnotstring);
9081cb0ef41Sopenharmony_ci    {
9091cb0ef41Sopenharmony_ci      var_tag = builtin_tag;
9101cb0ef41Sopenharmony_ci      Goto(&if_tagisstring);
9111cb0ef41Sopenharmony_ci    }
9121cb0ef41Sopenharmony_ci    BIND(&if_tagisstring);
9131cb0ef41Sopenharmony_ci    ReturnToStringFormat(context, CAST(var_tag.value()));
9141cb0ef41Sopenharmony_ci  }
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_ci  BIND(&if_regexp);
9171cb0ef41Sopenharmony_ci  {
9181cb0ef41Sopenharmony_ci    var_default = RegexpToStringConstant();
9191cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
9201cb0ef41Sopenharmony_ci  }
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci  BIND(&if_string);
9231cb0ef41Sopenharmony_ci  {
9241cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
9251cb0ef41Sopenharmony_ci    TNode<JSFunction> string_constructor = CAST(
9261cb0ef41Sopenharmony_ci        LoadContextElement(native_context, Context::STRING_FUNCTION_INDEX));
9271cb0ef41Sopenharmony_ci    TNode<Map> string_initial_map = LoadObjectField<Map>(
9281cb0ef41Sopenharmony_ci        string_constructor, JSFunction::kPrototypeOrInitialMapOffset);
9291cb0ef41Sopenharmony_ci    TNode<HeapObject> string_prototype =
9301cb0ef41Sopenharmony_ci        LoadObjectField<HeapObject>(string_initial_map, Map::kPrototypeOffset);
9311cb0ef41Sopenharmony_ci    var_default = StringToStringConstant();
9321cb0ef41Sopenharmony_ci    var_holder = string_prototype;
9331cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
9341cb0ef41Sopenharmony_ci  }
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ci  BIND(&if_symbol);
9371cb0ef41Sopenharmony_ci  {
9381cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
9391cb0ef41Sopenharmony_ci    TNode<JSFunction> symbol_constructor = CAST(
9401cb0ef41Sopenharmony_ci        LoadContextElement(native_context, Context::SYMBOL_FUNCTION_INDEX));
9411cb0ef41Sopenharmony_ci    TNode<Map> symbol_initial_map = LoadObjectField<Map>(
9421cb0ef41Sopenharmony_ci        symbol_constructor, JSFunction::kPrototypeOrInitialMapOffset);
9431cb0ef41Sopenharmony_ci    TNode<HeapObject> symbol_prototype =
9441cb0ef41Sopenharmony_ci        LoadObjectField<HeapObject>(symbol_initial_map, Map::kPrototypeOffset);
9451cb0ef41Sopenharmony_ci    var_default = ObjectToStringConstant();
9461cb0ef41Sopenharmony_ci    var_holder = symbol_prototype;
9471cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
9481cb0ef41Sopenharmony_ci  }
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_ci  BIND(&if_bigint);
9511cb0ef41Sopenharmony_ci  {
9521cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
9531cb0ef41Sopenharmony_ci    TNode<JSFunction> bigint_constructor = CAST(
9541cb0ef41Sopenharmony_ci        LoadContextElement(native_context, Context::BIGINT_FUNCTION_INDEX));
9551cb0ef41Sopenharmony_ci    TNode<Map> bigint_initial_map = LoadObjectField<Map>(
9561cb0ef41Sopenharmony_ci        bigint_constructor, JSFunction::kPrototypeOrInitialMapOffset);
9571cb0ef41Sopenharmony_ci    TNode<HeapObject> bigint_prototype =
9581cb0ef41Sopenharmony_ci        LoadObjectField<HeapObject>(bigint_initial_map, Map::kPrototypeOffset);
9591cb0ef41Sopenharmony_ci    var_default = ObjectToStringConstant();
9601cb0ef41Sopenharmony_ci    var_holder = bigint_prototype;
9611cb0ef41Sopenharmony_ci    Goto(&checkstringtag);
9621cb0ef41Sopenharmony_ci  }
9631cb0ef41Sopenharmony_ci
9641cb0ef41Sopenharmony_ci  BIND(&if_value);
9651cb0ef41Sopenharmony_ci  {
9661cb0ef41Sopenharmony_ci    Label if_value_is_number(this, Label::kDeferred),
9671cb0ef41Sopenharmony_ci        if_value_is_boolean(this, Label::kDeferred),
9681cb0ef41Sopenharmony_ci        if_value_is_symbol(this, Label::kDeferred),
9691cb0ef41Sopenharmony_ci        if_value_is_bigint(this, Label::kDeferred),
9701cb0ef41Sopenharmony_ci        if_value_is_string(this, Label::kDeferred);
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci    TNode<Object> receiver_value =
9731cb0ef41Sopenharmony_ci        LoadJSPrimitiveWrapperValue(CAST(receiver_heap_object));
9741cb0ef41Sopenharmony_ci    // We need to start with the object to see if the value was a subclass
9751cb0ef41Sopenharmony_ci    // which might have interesting properties.
9761cb0ef41Sopenharmony_ci    var_holder = receiver_heap_object;
9771cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(receiver_value), &if_value_is_number);
9781cb0ef41Sopenharmony_ci    TNode<Map> receiver_value_map = LoadMap(CAST(receiver_value));
9791cb0ef41Sopenharmony_ci    GotoIf(IsHeapNumberMap(receiver_value_map), &if_value_is_number);
9801cb0ef41Sopenharmony_ci    GotoIf(IsBooleanMap(receiver_value_map), &if_value_is_boolean);
9811cb0ef41Sopenharmony_ci    GotoIf(IsSymbolMap(receiver_value_map), &if_value_is_symbol);
9821cb0ef41Sopenharmony_ci    TNode<Uint16T> receiver_value_instance_type =
9831cb0ef41Sopenharmony_ci        LoadMapInstanceType(receiver_value_map);
9841cb0ef41Sopenharmony_ci    GotoIf(IsBigIntInstanceType(receiver_value_instance_type),
9851cb0ef41Sopenharmony_ci           &if_value_is_bigint);
9861cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsStringInstanceType(receiver_value_instance_type));
9871cb0ef41Sopenharmony_ci    Goto(&if_value_is_string);
9881cb0ef41Sopenharmony_ci
9891cb0ef41Sopenharmony_ci    BIND(&if_value_is_number);
9901cb0ef41Sopenharmony_ci    {
9911cb0ef41Sopenharmony_ci      var_default = NumberToStringConstant();
9921cb0ef41Sopenharmony_ci      Goto(&checkstringtag);
9931cb0ef41Sopenharmony_ci    }
9941cb0ef41Sopenharmony_ci
9951cb0ef41Sopenharmony_ci    BIND(&if_value_is_boolean);
9961cb0ef41Sopenharmony_ci    {
9971cb0ef41Sopenharmony_ci      var_default = BooleanToStringConstant();
9981cb0ef41Sopenharmony_ci      Goto(&checkstringtag);
9991cb0ef41Sopenharmony_ci    }
10001cb0ef41Sopenharmony_ci
10011cb0ef41Sopenharmony_ci    BIND(&if_value_is_string);
10021cb0ef41Sopenharmony_ci    {
10031cb0ef41Sopenharmony_ci      var_default = StringToStringConstant();
10041cb0ef41Sopenharmony_ci      Goto(&checkstringtag);
10051cb0ef41Sopenharmony_ci    }
10061cb0ef41Sopenharmony_ci
10071cb0ef41Sopenharmony_ci    BIND(&if_value_is_bigint);
10081cb0ef41Sopenharmony_ci    {
10091cb0ef41Sopenharmony_ci      var_default = ObjectToStringConstant();
10101cb0ef41Sopenharmony_ci      Goto(&checkstringtag);
10111cb0ef41Sopenharmony_ci    }
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_ci    BIND(&if_value_is_symbol);
10141cb0ef41Sopenharmony_ci    {
10151cb0ef41Sopenharmony_ci      var_default = ObjectToStringConstant();
10161cb0ef41Sopenharmony_ci      Goto(&checkstringtag);
10171cb0ef41Sopenharmony_ci    }
10181cb0ef41Sopenharmony_ci  }
10191cb0ef41Sopenharmony_ci
10201cb0ef41Sopenharmony_ci  BIND(&checkstringtag);
10211cb0ef41Sopenharmony_ci  {
10221cb0ef41Sopenharmony_ci    // Check if all relevant maps (including the prototype maps) don't
10231cb0ef41Sopenharmony_ci    // have any interesting symbols (i.e. that none of them have the
10241cb0ef41Sopenharmony_ci    // @@toStringTag property).
10251cb0ef41Sopenharmony_ci    Label loop(this, &var_holder), return_default(this),
10261cb0ef41Sopenharmony_ci        return_generic(this, Label::kDeferred);
10271cb0ef41Sopenharmony_ci    Goto(&loop);
10281cb0ef41Sopenharmony_ci    BIND(&loop);
10291cb0ef41Sopenharmony_ci    {
10301cb0ef41Sopenharmony_ci      TNode<HeapObject> holder = var_holder.value();
10311cb0ef41Sopenharmony_ci      GotoIf(IsNull(holder), &return_default);
10321cb0ef41Sopenharmony_ci      TNode<Map> holder_map = LoadMap(holder);
10331cb0ef41Sopenharmony_ci      TNode<Uint32T> holder_bit_field3 = LoadMapBitField3(holder_map);
10341cb0ef41Sopenharmony_ci      GotoIf(IsSetWord32<Map::Bits3::MayHaveInterestingSymbolsBit>(
10351cb0ef41Sopenharmony_ci                 holder_bit_field3),
10361cb0ef41Sopenharmony_ci             &return_generic);
10371cb0ef41Sopenharmony_ci      var_holder = LoadMapPrototype(holder_map);
10381cb0ef41Sopenharmony_ci      Goto(&loop);
10391cb0ef41Sopenharmony_ci    }
10401cb0ef41Sopenharmony_ci
10411cb0ef41Sopenharmony_ci    BIND(&return_generic);
10421cb0ef41Sopenharmony_ci    {
10431cb0ef41Sopenharmony_ci      TNode<Object> tag = GetProperty(context, ToObject(context, receiver),
10441cb0ef41Sopenharmony_ci                                      ToStringTagSymbolConstant());
10451cb0ef41Sopenharmony_ci      GotoIf(TaggedIsSmi(tag), &return_default);
10461cb0ef41Sopenharmony_ci      GotoIfNot(IsString(CAST(tag)), &return_default);
10471cb0ef41Sopenharmony_ci      ReturnToStringFormat(context, CAST(tag));
10481cb0ef41Sopenharmony_ci    }
10491cb0ef41Sopenharmony_ci
10501cb0ef41Sopenharmony_ci    BIND(&return_default);
10511cb0ef41Sopenharmony_ci    Return(var_default.value());
10521cb0ef41Sopenharmony_ci  }
10531cb0ef41Sopenharmony_ci}
10541cb0ef41Sopenharmony_ci
10551cb0ef41Sopenharmony_ci// ES #sec-object.create
10561cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
10571cb0ef41Sopenharmony_ci  int const kPrototypeArg = 0;
10581cb0ef41Sopenharmony_ci  int const kPropertiesArg = 1;
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_ci  TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
10611cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
10621cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
10631cb0ef41Sopenharmony_ci
10641cb0ef41Sopenharmony_ci  TNode<Object> prototype = args.GetOptionalArgumentValue(kPrototypeArg);
10651cb0ef41Sopenharmony_ci  TNode<Object> properties = args.GetOptionalArgumentValue(kPropertiesArg);
10661cb0ef41Sopenharmony_ci  auto native_context = Parameter<NativeContext>(Descriptor::kContext);
10671cb0ef41Sopenharmony_ci
10681cb0ef41Sopenharmony_ci  Label call_runtime(this, Label::kDeferred), prototype_valid(this),
10691cb0ef41Sopenharmony_ci      no_properties(this);
10701cb0ef41Sopenharmony_ci
10711cb0ef41Sopenharmony_ci  {
10721cb0ef41Sopenharmony_ci    Comment("Argument 1 check: prototype");
10731cb0ef41Sopenharmony_ci    GotoIf(IsNull(prototype), &prototype_valid);
10741cb0ef41Sopenharmony_ci    BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime);
10751cb0ef41Sopenharmony_ci  }
10761cb0ef41Sopenharmony_ci
10771cb0ef41Sopenharmony_ci  BIND(&prototype_valid);
10781cb0ef41Sopenharmony_ci  {
10791cb0ef41Sopenharmony_ci    Comment("Argument 2 check: properties");
10801cb0ef41Sopenharmony_ci    // Check that we have a simple object
10811cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(properties), &call_runtime);
10821cb0ef41Sopenharmony_ci    // Undefined implies no properties.
10831cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(properties), &no_properties);
10841cb0ef41Sopenharmony_ci    TNode<Map> properties_map = LoadMap(CAST(properties));
10851cb0ef41Sopenharmony_ci    GotoIf(IsSpecialReceiverMap(properties_map), &call_runtime);
10861cb0ef41Sopenharmony_ci    // Stay on the fast path only if there are no elements.
10871cb0ef41Sopenharmony_ci    GotoIfNot(
10881cb0ef41Sopenharmony_ci        TaggedEqual(LoadElements(CAST(properties)), EmptyFixedArrayConstant()),
10891cb0ef41Sopenharmony_ci        &call_runtime);
10901cb0ef41Sopenharmony_ci    // Handle dictionary objects or fast objects with properties in runtime.
10911cb0ef41Sopenharmony_ci    TNode<Uint32T> bit_field3 = LoadMapBitField3(properties_map);
10921cb0ef41Sopenharmony_ci    GotoIf(IsSetWord32<Map::Bits3::IsDictionaryMapBit>(bit_field3),
10931cb0ef41Sopenharmony_ci           &call_runtime);
10941cb0ef41Sopenharmony_ci    Branch(IsSetWord32<Map::Bits3::NumberOfOwnDescriptorsBits>(bit_field3),
10951cb0ef41Sopenharmony_ci           &call_runtime, &no_properties);
10961cb0ef41Sopenharmony_ci  }
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci  // Create a new object with the given prototype.
10991cb0ef41Sopenharmony_ci  BIND(&no_properties);
11001cb0ef41Sopenharmony_ci  {
11011cb0ef41Sopenharmony_ci    TVARIABLE(Map, map);
11021cb0ef41Sopenharmony_ci    TVARIABLE(HeapObject, new_properties);
11031cb0ef41Sopenharmony_ci    Label null_proto(this), non_null_proto(this), instantiate_map(this);
11041cb0ef41Sopenharmony_ci
11051cb0ef41Sopenharmony_ci    Branch(IsNull(prototype), &null_proto, &non_null_proto);
11061cb0ef41Sopenharmony_ci
11071cb0ef41Sopenharmony_ci    BIND(&null_proto);
11081cb0ef41Sopenharmony_ci    {
11091cb0ef41Sopenharmony_ci      map = LoadSlowObjectWithNullPrototypeMap(native_context);
11101cb0ef41Sopenharmony_ci      if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
11111cb0ef41Sopenharmony_ci        new_properties =
11121cb0ef41Sopenharmony_ci            AllocateSwissNameDictionary(SwissNameDictionary::kInitialCapacity);
11131cb0ef41Sopenharmony_ci      } else {
11141cb0ef41Sopenharmony_ci        new_properties =
11151cb0ef41Sopenharmony_ci            AllocateNameDictionary(NameDictionary::kInitialCapacity);
11161cb0ef41Sopenharmony_ci      }
11171cb0ef41Sopenharmony_ci      Goto(&instantiate_map);
11181cb0ef41Sopenharmony_ci    }
11191cb0ef41Sopenharmony_ci
11201cb0ef41Sopenharmony_ci    BIND(&non_null_proto);
11211cb0ef41Sopenharmony_ci    {
11221cb0ef41Sopenharmony_ci      new_properties = EmptyFixedArrayConstant();
11231cb0ef41Sopenharmony_ci      map = LoadObjectFunctionInitialMap(native_context);
11241cb0ef41Sopenharmony_ci      GotoIf(TaggedEqual(prototype, LoadMapPrototype(map.value())),
11251cb0ef41Sopenharmony_ci             &instantiate_map);
11261cb0ef41Sopenharmony_ci      // Try loading the prototype info.
11271cb0ef41Sopenharmony_ci      TNode<PrototypeInfo> prototype_info =
11281cb0ef41Sopenharmony_ci          LoadMapPrototypeInfo(LoadMap(CAST(prototype)), &call_runtime);
11291cb0ef41Sopenharmony_ci      Comment("Load ObjectCreateMap from PrototypeInfo");
11301cb0ef41Sopenharmony_ci      TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField(
11311cb0ef41Sopenharmony_ci          prototype_info, PrototypeInfo::kObjectCreateMapOffset);
11321cb0ef41Sopenharmony_ci      GotoIf(TaggedEqual(maybe_map, UndefinedConstant()), &call_runtime);
11331cb0ef41Sopenharmony_ci      map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime));
11341cb0ef41Sopenharmony_ci      Goto(&instantiate_map);
11351cb0ef41Sopenharmony_ci    }
11361cb0ef41Sopenharmony_ci
11371cb0ef41Sopenharmony_ci    BIND(&instantiate_map);
11381cb0ef41Sopenharmony_ci    {
11391cb0ef41Sopenharmony_ci      TNode<JSObject> instance =
11401cb0ef41Sopenharmony_ci          AllocateJSObjectFromMap(map.value(), new_properties.value());
11411cb0ef41Sopenharmony_ci      args.PopAndReturn(instance);
11421cb0ef41Sopenharmony_ci    }
11431cb0ef41Sopenharmony_ci  }
11441cb0ef41Sopenharmony_ci
11451cb0ef41Sopenharmony_ci  BIND(&call_runtime);
11461cb0ef41Sopenharmony_ci  {
11471cb0ef41Sopenharmony_ci    TNode<Object> result = CallRuntime(Runtime::kObjectCreate, native_context,
11481cb0ef41Sopenharmony_ci                                       prototype, properties);
11491cb0ef41Sopenharmony_ci    args.PopAndReturn(result);
11501cb0ef41Sopenharmony_ci  }
11511cb0ef41Sopenharmony_ci}
11521cb0ef41Sopenharmony_ci
11531cb0ef41Sopenharmony_ci// ES #sec-object.is
11541cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectIs, ObjectBuiltinsAssembler) {
11551cb0ef41Sopenharmony_ci  const auto left = Parameter<Object>(Descriptor::kLeft);
11561cb0ef41Sopenharmony_ci  const auto right = Parameter<Object>(Descriptor::kRight);
11571cb0ef41Sopenharmony_ci
11581cb0ef41Sopenharmony_ci  Label return_true(this), return_false(this);
11591cb0ef41Sopenharmony_ci  BranchIfSameValue(left, right, &return_true, &return_false);
11601cb0ef41Sopenharmony_ci
11611cb0ef41Sopenharmony_ci  BIND(&return_true);
11621cb0ef41Sopenharmony_ci  Return(TrueConstant());
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ci  BIND(&return_false);
11651cb0ef41Sopenharmony_ci  Return(FalseConstant());
11661cb0ef41Sopenharmony_ci}
11671cb0ef41Sopenharmony_ci
11681cb0ef41Sopenharmony_ciTF_BUILTIN(CreateIterResultObject, ObjectBuiltinsAssembler) {
11691cb0ef41Sopenharmony_ci  const auto value = Parameter<Object>(Descriptor::kValue);
11701cb0ef41Sopenharmony_ci  const auto done = Parameter<Oddball>(Descriptor::kDone);
11711cb0ef41Sopenharmony_ci  const auto context = Parameter<Context>(Descriptor::kContext);
11721cb0ef41Sopenharmony_ci
11731cb0ef41Sopenharmony_ci  const TNode<NativeContext> native_context = LoadNativeContext(context);
11741cb0ef41Sopenharmony_ci  const TNode<Map> map = CAST(
11751cb0ef41Sopenharmony_ci      LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX));
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_ci  const TNode<JSObject> result = AllocateJSObjectFromMap(map);
11781cb0ef41Sopenharmony_ci
11791cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, value);
11801cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset, done);
11811cb0ef41Sopenharmony_ci
11821cb0ef41Sopenharmony_ci  Return(result);
11831cb0ef41Sopenharmony_ci}
11841cb0ef41Sopenharmony_ci
11851cb0ef41Sopenharmony_ciTF_BUILTIN(HasProperty, ObjectBuiltinsAssembler) {
11861cb0ef41Sopenharmony_ci  auto key = Parameter<Object>(Descriptor::kKey);
11871cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kObject);
11881cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
11891cb0ef41Sopenharmony_ci
11901cb0ef41Sopenharmony_ci  Return(HasProperty(context, object, key, kHasProperty));
11911cb0ef41Sopenharmony_ci}
11921cb0ef41Sopenharmony_ci
11931cb0ef41Sopenharmony_ciTF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) {
11941cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kLeft);
11951cb0ef41Sopenharmony_ci  auto callable = Parameter<Object>(Descriptor::kRight);
11961cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
11971cb0ef41Sopenharmony_ci
11981cb0ef41Sopenharmony_ci  Return(InstanceOf(object, callable, context));
11991cb0ef41Sopenharmony_ci}
12001cb0ef41Sopenharmony_ci
12011cb0ef41Sopenharmony_ciTF_BUILTIN(InstanceOf_WithFeedback, ObjectBuiltinsAssembler) {
12021cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kLeft);
12031cb0ef41Sopenharmony_ci  auto callable = Parameter<Object>(Descriptor::kRight);
12041cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
12051cb0ef41Sopenharmony_ci  auto feedback_vector = Parameter<HeapObject>(Descriptor::kFeedbackVector);
12061cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci  CollectInstanceOfFeedback(callable, context, feedback_vector, slot);
12091cb0ef41Sopenharmony_ci  Return(InstanceOf(object, callable, context));
12101cb0ef41Sopenharmony_ci}
12111cb0ef41Sopenharmony_ci
12121cb0ef41Sopenharmony_ciTF_BUILTIN(InstanceOf_Baseline, ObjectBuiltinsAssembler) {
12131cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kLeft);
12141cb0ef41Sopenharmony_ci  auto callable = Parameter<Object>(Descriptor::kRight);
12151cb0ef41Sopenharmony_ci  auto context = LoadContextFromBaseline();
12161cb0ef41Sopenharmony_ci  auto feedback_vector = LoadFeedbackVectorFromBaseline();
12171cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
12181cb0ef41Sopenharmony_ci
12191cb0ef41Sopenharmony_ci  CollectInstanceOfFeedback(callable, context, feedback_vector, slot);
12201cb0ef41Sopenharmony_ci  Return(InstanceOf(object, callable, context));
12211cb0ef41Sopenharmony_ci}
12221cb0ef41Sopenharmony_ci
12231cb0ef41Sopenharmony_ci// ES6 section 7.3.19 OrdinaryHasInstance ( C, O )
12241cb0ef41Sopenharmony_ciTF_BUILTIN(OrdinaryHasInstance, ObjectBuiltinsAssembler) {
12251cb0ef41Sopenharmony_ci  auto constructor = Parameter<Object>(Descriptor::kLeft);
12261cb0ef41Sopenharmony_ci  auto object = Parameter<Object>(Descriptor::kRight);
12271cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
12281cb0ef41Sopenharmony_ci
12291cb0ef41Sopenharmony_ci  Return(OrdinaryHasInstance(context, constructor, object));
12301cb0ef41Sopenharmony_ci}
12311cb0ef41Sopenharmony_ci
12321cb0ef41Sopenharmony_ciTF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) {
12331cb0ef41Sopenharmony_ci  auto closure = Parameter<JSFunction>(Descriptor::kClosure);
12341cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
12351cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
12361cb0ef41Sopenharmony_ci
12371cb0ef41Sopenharmony_ci  // Get the initial map from the function, jumping to the runtime if we don't
12381cb0ef41Sopenharmony_ci  // have one.
12391cb0ef41Sopenharmony_ci  Label done(this), runtime(this);
12401cb0ef41Sopenharmony_ci  GotoIfNot(IsFunctionWithPrototypeSlotMap(LoadMap(closure)), &runtime);
12411cb0ef41Sopenharmony_ci  TNode<HeapObject> maybe_map = LoadObjectField<HeapObject>(
12421cb0ef41Sopenharmony_ci      closure, JSFunction::kPrototypeOrInitialMapOffset);
12431cb0ef41Sopenharmony_ci  GotoIf(DoesntHaveInstanceType(maybe_map, MAP_TYPE), &runtime);
12441cb0ef41Sopenharmony_ci  TNode<Map> map = CAST(maybe_map);
12451cb0ef41Sopenharmony_ci
12461cb0ef41Sopenharmony_ci  TNode<SharedFunctionInfo> shared = LoadObjectField<SharedFunctionInfo>(
12471cb0ef41Sopenharmony_ci      closure, JSFunction::kSharedFunctionInfoOffset);
12481cb0ef41Sopenharmony_ci  TNode<BytecodeArray> bytecode_array =
12491cb0ef41Sopenharmony_ci      LoadSharedFunctionInfoBytecodeArray(shared);
12501cb0ef41Sopenharmony_ci
12511cb0ef41Sopenharmony_ci  TNode<IntPtrT> formal_parameter_count = ChangeInt32ToIntPtr(
12521cb0ef41Sopenharmony_ci      LoadSharedFunctionInfoFormalParameterCountWithoutReceiver(shared));
12531cb0ef41Sopenharmony_ci  TNode<IntPtrT> frame_size = ChangeInt32ToIntPtr(
12541cb0ef41Sopenharmony_ci      LoadObjectField<Int32T>(bytecode_array, BytecodeArray::kFrameSizeOffset));
12551cb0ef41Sopenharmony_ci  TNode<IntPtrT> size =
12561cb0ef41Sopenharmony_ci      IntPtrAdd(WordSar(frame_size, IntPtrConstant(kTaggedSizeLog2)),
12571cb0ef41Sopenharmony_ci                formal_parameter_count);
12581cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> parameters_and_registers = AllocateFixedArray(
12591cb0ef41Sopenharmony_ci      HOLEY_ELEMENTS, size, AllocationFlag::kAllowLargeObjectAllocation);
12601cb0ef41Sopenharmony_ci  FillFixedArrayWithValue(HOLEY_ELEMENTS, parameters_and_registers,
12611cb0ef41Sopenharmony_ci                          IntPtrConstant(0), size, RootIndex::kUndefinedValue);
12621cb0ef41Sopenharmony_ci  // TODO(cbruni): support start_offset to avoid double initialization.
12631cb0ef41Sopenharmony_ci  TNode<JSObject> result =
12641cb0ef41Sopenharmony_ci      AllocateJSObjectFromMap(map, base::nullopt, base::nullopt,
12651cb0ef41Sopenharmony_ci                              AllocationFlag::kNone, kWithSlackTracking);
12661cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kFunctionOffset,
12671cb0ef41Sopenharmony_ci                                 closure);
12681cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kContextOffset,
12691cb0ef41Sopenharmony_ci                                 context);
12701cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kReceiverOffset,
12711cb0ef41Sopenharmony_ci                                 receiver);
12721cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
12731cb0ef41Sopenharmony_ci      result, JSGeneratorObject::kParametersAndRegistersOffset,
12741cb0ef41Sopenharmony_ci      parameters_and_registers);
12751cb0ef41Sopenharmony_ci  TNode<Smi> resume_mode = SmiConstant(JSGeneratorObject::ResumeMode::kNext);
12761cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kResumeModeOffset,
12771cb0ef41Sopenharmony_ci                                 resume_mode);
12781cb0ef41Sopenharmony_ci  TNode<Smi> executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting);
12791cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kContinuationOffset,
12801cb0ef41Sopenharmony_ci                                 executing);
12811cb0ef41Sopenharmony_ci  GotoIfNot(InstanceTypeEqual(LoadMapInstanceType(map),
12821cb0ef41Sopenharmony_ci                              JS_ASYNC_GENERATOR_OBJECT_TYPE),
12831cb0ef41Sopenharmony_ci            &done);
12841cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(
12851cb0ef41Sopenharmony_ci      result, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0));
12861cb0ef41Sopenharmony_ci  Goto(&done);
12871cb0ef41Sopenharmony_ci
12881cb0ef41Sopenharmony_ci  BIND(&done);
12891cb0ef41Sopenharmony_ci  { Return(result); }
12901cb0ef41Sopenharmony_ci
12911cb0ef41Sopenharmony_ci  BIND(&runtime);
12921cb0ef41Sopenharmony_ci  {
12931cb0ef41Sopenharmony_ci    Return(CallRuntime(Runtime::kCreateJSGeneratorObject, context, closure,
12941cb0ef41Sopenharmony_ci                       receiver));
12951cb0ef41Sopenharmony_ci  }
12961cb0ef41Sopenharmony_ci}
12971cb0ef41Sopenharmony_ci
12981cb0ef41Sopenharmony_ci// ES6 section 19.1.2.7 Object.getOwnPropertyDescriptor ( O, P )
12991cb0ef41Sopenharmony_ciTF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
13001cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount);
13011cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
13021cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsUndefined(Parameter<Object>(Descriptor::kJSNewTarget)));
13031cb0ef41Sopenharmony_ci
13041cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
13051cb0ef41Sopenharmony_ci  TNode<Object> object_input = args.GetOptionalArgumentValue(0);
13061cb0ef41Sopenharmony_ci  TNode<Object> key = args.GetOptionalArgumentValue(1);
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ci  // 1. Let obj be ? ToObject(O).
13091cb0ef41Sopenharmony_ci  TNode<JSReceiver> object = ToObject_Inline(context, object_input);
13101cb0ef41Sopenharmony_ci
13111cb0ef41Sopenharmony_ci  // 2. Let key be ? ToPropertyKey(P).
13121cb0ef41Sopenharmony_ci  key = CallBuiltin(Builtin::kToName, context, key);
13131cb0ef41Sopenharmony_ci
13141cb0ef41Sopenharmony_ci  // 3. Let desc be ? obj.[[GetOwnProperty]](key).
13151cb0ef41Sopenharmony_ci  Label if_keyisindex(this), if_iskeyunique(this),
13161cb0ef41Sopenharmony_ci      call_runtime(this, Label::kDeferred),
13171cb0ef41Sopenharmony_ci      return_undefined(this, Label::kDeferred), if_notunique_name(this);
13181cb0ef41Sopenharmony_ci
13191cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(object);
13201cb0ef41Sopenharmony_ci  TNode<Uint16T> instance_type = LoadMapInstanceType(map);
13211cb0ef41Sopenharmony_ci  GotoIf(IsSpecialReceiverInstanceType(instance_type), &call_runtime);
13221cb0ef41Sopenharmony_ci  {
13231cb0ef41Sopenharmony_ci    TVARIABLE(IntPtrT, var_index, IntPtrConstant(0));
13241cb0ef41Sopenharmony_ci    TVARIABLE(Name, var_name);
13251cb0ef41Sopenharmony_ci
13261cb0ef41Sopenharmony_ci    TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_name,
13271cb0ef41Sopenharmony_ci              &call_runtime, &if_notunique_name);
13281cb0ef41Sopenharmony_ci
13291cb0ef41Sopenharmony_ci    BIND(&if_notunique_name);
13301cb0ef41Sopenharmony_ci    {
13311cb0ef41Sopenharmony_ci      Label not_in_string_table(this);
13321cb0ef41Sopenharmony_ci      TryInternalizeString(CAST(key), &if_keyisindex, &var_index,
13331cb0ef41Sopenharmony_ci                           &if_iskeyunique, &var_name, &not_in_string_table,
13341cb0ef41Sopenharmony_ci                           &call_runtime);
13351cb0ef41Sopenharmony_ci
13361cb0ef41Sopenharmony_ci      BIND(&not_in_string_table);
13371cb0ef41Sopenharmony_ci      {
13381cb0ef41Sopenharmony_ci        // If the string was not found in the string table, then no regular
13391cb0ef41Sopenharmony_ci        // object can have a property with that name, so return |undefined|.
13401cb0ef41Sopenharmony_ci        Goto(&return_undefined);
13411cb0ef41Sopenharmony_ci      }
13421cb0ef41Sopenharmony_ci    }
13431cb0ef41Sopenharmony_ci
13441cb0ef41Sopenharmony_ci    BIND(&if_iskeyunique);
13451cb0ef41Sopenharmony_ci    {
13461cb0ef41Sopenharmony_ci      Label if_found_value(this), return_empty(this), if_not_found(this);
13471cb0ef41Sopenharmony_ci
13481cb0ef41Sopenharmony_ci      TVARIABLE(Object, var_value);
13491cb0ef41Sopenharmony_ci      TVARIABLE(Uint32T, var_details);
13501cb0ef41Sopenharmony_ci      TVARIABLE(Object, var_raw_value);
13511cb0ef41Sopenharmony_ci
13521cb0ef41Sopenharmony_ci      TryGetOwnProperty(context, object, object, map, instance_type,
13531cb0ef41Sopenharmony_ci                        var_name.value(), &if_found_value, &var_value,
13541cb0ef41Sopenharmony_ci                        &var_details, &var_raw_value, &return_empty,
13551cb0ef41Sopenharmony_ci                        &if_not_found, kReturnAccessorPair);
13561cb0ef41Sopenharmony_ci
13571cb0ef41Sopenharmony_ci      BIND(&if_found_value);
13581cb0ef41Sopenharmony_ci      // 4. Return FromPropertyDetails(desc).
13591cb0ef41Sopenharmony_ci      TNode<JSObject> js_desc = FromPropertyDetails(
13601cb0ef41Sopenharmony_ci          context, var_value.value(), var_details.value(), &call_runtime);
13611cb0ef41Sopenharmony_ci      args.PopAndReturn(js_desc);
13621cb0ef41Sopenharmony_ci
13631cb0ef41Sopenharmony_ci      BIND(&return_empty);
13641cb0ef41Sopenharmony_ci      var_value = UndefinedConstant();
13651cb0ef41Sopenharmony_ci      args.PopAndReturn(UndefinedConstant());
13661cb0ef41Sopenharmony_ci
13671cb0ef41Sopenharmony_ci      BIND(&if_not_found);
13681cb0ef41Sopenharmony_ci      Goto(&call_runtime);
13691cb0ef41Sopenharmony_ci    }
13701cb0ef41Sopenharmony_ci  }
13711cb0ef41Sopenharmony_ci
13721cb0ef41Sopenharmony_ci  BIND(&if_keyisindex);
13731cb0ef41Sopenharmony_ci  Goto(&call_runtime);
13741cb0ef41Sopenharmony_ci
13751cb0ef41Sopenharmony_ci  BIND(&call_runtime);
13761cb0ef41Sopenharmony_ci  {
13771cb0ef41Sopenharmony_ci    TNode<Object> desc =
13781cb0ef41Sopenharmony_ci        CallRuntime(Runtime::kGetOwnPropertyDescriptor, context, object, key);
13791cb0ef41Sopenharmony_ci
13801cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(desc), &return_undefined);
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_ci    TNode<PropertyDescriptorObject> desc_object = CAST(desc);
13831cb0ef41Sopenharmony_ci
13841cb0ef41Sopenharmony_ci    // 4. Return FromPropertyDescriptor(desc).
13851cb0ef41Sopenharmony_ci    TNode<JSObject> js_desc = FromPropertyDescriptor(context, desc_object);
13861cb0ef41Sopenharmony_ci    args.PopAndReturn(js_desc);
13871cb0ef41Sopenharmony_ci  }
13881cb0ef41Sopenharmony_ci  BIND(&return_undefined);
13891cb0ef41Sopenharmony_ci  args.PopAndReturn(UndefinedConstant());
13901cb0ef41Sopenharmony_ci}
13911cb0ef41Sopenharmony_ci
13921cb0ef41Sopenharmony_ci// TODO(v8:11167) remove remove |context| and |object| parameters once
13931cb0ef41Sopenharmony_ci// OrderedNameDictionary supported.
13941cb0ef41Sopenharmony_civoid ObjectBuiltinsAssembler::AddToDictionaryIf(
13951cb0ef41Sopenharmony_ci    TNode<BoolT> condition, TNode<Context> context, TNode<Object> object,
13961cb0ef41Sopenharmony_ci    TNode<HeapObject> name_dictionary, Handle<Name> name, TNode<Object> value,
13971cb0ef41Sopenharmony_ci    Label* bailout) {
13981cb0ef41Sopenharmony_ci  Label done(this);
13991cb0ef41Sopenharmony_ci  GotoIfNot(condition, &done);
14001cb0ef41Sopenharmony_ci
14011cb0ef41Sopenharmony_ci  Add<PropertyDictionary>(CAST(name_dictionary), HeapConstant(name), value,
14021cb0ef41Sopenharmony_ci                          bailout);
14031cb0ef41Sopenharmony_ci  Goto(&done);
14041cb0ef41Sopenharmony_ci
14051cb0ef41Sopenharmony_ci  BIND(&done);
14061cb0ef41Sopenharmony_ci}
14071cb0ef41Sopenharmony_ci
14081cb0ef41Sopenharmony_ciTNode<JSObject> ObjectBuiltinsAssembler::FromPropertyDescriptor(
14091cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<PropertyDescriptorObject> desc) {
14101cb0ef41Sopenharmony_ci  TVARIABLE(JSObject, js_descriptor);
14111cb0ef41Sopenharmony_ci
14121cb0ef41Sopenharmony_ci  TNode<Int32T> flags = LoadAndUntagToWord32ObjectField(
14131cb0ef41Sopenharmony_ci      desc, PropertyDescriptorObject::kFlagsOffset);
14141cb0ef41Sopenharmony_ci
14151cb0ef41Sopenharmony_ci  TNode<Int32T> has_flags =
14161cb0ef41Sopenharmony_ci      Word32And(flags, Int32Constant(PropertyDescriptorObject::kHasMask));
14171cb0ef41Sopenharmony_ci
14181cb0ef41Sopenharmony_ci  Label if_accessor_desc(this), if_data_desc(this), if_generic_desc(this),
14191cb0ef41Sopenharmony_ci      return_desc(this);
14201cb0ef41Sopenharmony_ci  GotoIf(
14211cb0ef41Sopenharmony_ci      Word32Equal(has_flags,
14221cb0ef41Sopenharmony_ci                  Int32Constant(
14231cb0ef41Sopenharmony_ci                      PropertyDescriptorObject::kRegularAccessorPropertyBits)),
14241cb0ef41Sopenharmony_ci      &if_accessor_desc);
14251cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(
14261cb0ef41Sopenharmony_ci             has_flags,
14271cb0ef41Sopenharmony_ci             Int32Constant(PropertyDescriptorObject::kRegularDataPropertyBits)),
14281cb0ef41Sopenharmony_ci         &if_data_desc);
14291cb0ef41Sopenharmony_ci  Goto(&if_generic_desc);
14301cb0ef41Sopenharmony_ci
14311cb0ef41Sopenharmony_ci  BIND(&if_accessor_desc);
14321cb0ef41Sopenharmony_ci  {
14331cb0ef41Sopenharmony_ci    js_descriptor = ConstructAccessorDescriptor(
14341cb0ef41Sopenharmony_ci        context, LoadObjectField(desc, PropertyDescriptorObject::kGetOffset),
14351cb0ef41Sopenharmony_ci        LoadObjectField(desc, PropertyDescriptorObject::kSetOffset),
14361cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::IsEnumerableBit>(flags),
14371cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags));
14381cb0ef41Sopenharmony_ci    Goto(&return_desc);
14391cb0ef41Sopenharmony_ci  }
14401cb0ef41Sopenharmony_ci
14411cb0ef41Sopenharmony_ci  BIND(&if_data_desc);
14421cb0ef41Sopenharmony_ci  {
14431cb0ef41Sopenharmony_ci    js_descriptor = ConstructDataDescriptor(
14441cb0ef41Sopenharmony_ci        context, LoadObjectField(desc, PropertyDescriptorObject::kValueOffset),
14451cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::IsWritableBit>(flags),
14461cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::IsEnumerableBit>(flags),
14471cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags));
14481cb0ef41Sopenharmony_ci    Goto(&return_desc);
14491cb0ef41Sopenharmony_ci  }
14501cb0ef41Sopenharmony_ci
14511cb0ef41Sopenharmony_ci  BIND(&if_generic_desc);
14521cb0ef41Sopenharmony_ci  {
14531cb0ef41Sopenharmony_ci    TNode<NativeContext> native_context = LoadNativeContext(context);
14541cb0ef41Sopenharmony_ci    TNode<Map> map = CAST(LoadContextElement(
14551cb0ef41Sopenharmony_ci        native_context, Context::SLOW_OBJECT_WITH_OBJECT_PROTOTYPE_MAP));
14561cb0ef41Sopenharmony_ci    // We want to preallocate the slots for value, writable, get, set,
14571cb0ef41Sopenharmony_ci    // enumerable and configurable - a total of 6
14581cb0ef41Sopenharmony_ci    TNode<HeapObject> properties =
14591cb0ef41Sopenharmony_ci        V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
14601cb0ef41Sopenharmony_ci            ? TNode<HeapObject>(AllocateSwissNameDictionary(6))
14611cb0ef41Sopenharmony_ci            : AllocateNameDictionary(6);
14621cb0ef41Sopenharmony_ci    TNode<JSObject> js_desc = AllocateJSObjectFromMap(map, properties);
14631cb0ef41Sopenharmony_ci
14641cb0ef41Sopenharmony_ci    Label bailout(this, Label::kDeferred);
14651cb0ef41Sopenharmony_ci
14661cb0ef41Sopenharmony_ci    Factory* factory = isolate()->factory();
14671cb0ef41Sopenharmony_ci    TNode<Object> value =
14681cb0ef41Sopenharmony_ci        LoadObjectField(desc, PropertyDescriptorObject::kValueOffset);
14691cb0ef41Sopenharmony_ci    AddToDictionaryIf(IsNotTheHole(value), context, js_desc, properties,
14701cb0ef41Sopenharmony_ci                      factory->value_string(), value, &bailout);
14711cb0ef41Sopenharmony_ci    AddToDictionaryIf(
14721cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::HasWritableBit>(flags), context,
14731cb0ef41Sopenharmony_ci        js_desc, properties, factory->writable_string(),
14741cb0ef41Sopenharmony_ci        SelectBooleanConstant(
14751cb0ef41Sopenharmony_ci            IsSetWord32<PropertyDescriptorObject::IsWritableBit>(flags)),
14761cb0ef41Sopenharmony_ci        &bailout);
14771cb0ef41Sopenharmony_ci
14781cb0ef41Sopenharmony_ci    TNode<Object> get =
14791cb0ef41Sopenharmony_ci        LoadObjectField(desc, PropertyDescriptorObject::kGetOffset);
14801cb0ef41Sopenharmony_ci    AddToDictionaryIf(IsNotTheHole(get), context, js_desc, properties,
14811cb0ef41Sopenharmony_ci                      factory->get_string(), get, &bailout);
14821cb0ef41Sopenharmony_ci    TNode<Object> set =
14831cb0ef41Sopenharmony_ci        LoadObjectField(desc, PropertyDescriptorObject::kSetOffset);
14841cb0ef41Sopenharmony_ci    AddToDictionaryIf(IsNotTheHole(set), context, js_desc, properties,
14851cb0ef41Sopenharmony_ci                      factory->set_string(), set, &bailout);
14861cb0ef41Sopenharmony_ci
14871cb0ef41Sopenharmony_ci    AddToDictionaryIf(
14881cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::HasEnumerableBit>(flags), context,
14891cb0ef41Sopenharmony_ci        js_desc, properties, factory->enumerable_string(),
14901cb0ef41Sopenharmony_ci        SelectBooleanConstant(
14911cb0ef41Sopenharmony_ci            IsSetWord32<PropertyDescriptorObject::IsEnumerableBit>(flags)),
14921cb0ef41Sopenharmony_ci        &bailout);
14931cb0ef41Sopenharmony_ci    AddToDictionaryIf(
14941cb0ef41Sopenharmony_ci        IsSetWord32<PropertyDescriptorObject::HasConfigurableBit>(flags),
14951cb0ef41Sopenharmony_ci        context, js_desc, properties, factory->configurable_string(),
14961cb0ef41Sopenharmony_ci        SelectBooleanConstant(
14971cb0ef41Sopenharmony_ci            IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags)),
14981cb0ef41Sopenharmony_ci        &bailout);
14991cb0ef41Sopenharmony_ci
15001cb0ef41Sopenharmony_ci    js_descriptor = js_desc;
15011cb0ef41Sopenharmony_ci    Goto(&return_desc);
15021cb0ef41Sopenharmony_ci
15031cb0ef41Sopenharmony_ci    BIND(&bailout);
15041cb0ef41Sopenharmony_ci    CSA_DCHECK(this, Int32Constant(0));
15051cb0ef41Sopenharmony_ci    Unreachable();
15061cb0ef41Sopenharmony_ci  }
15071cb0ef41Sopenharmony_ci
15081cb0ef41Sopenharmony_ci  BIND(&return_desc);
15091cb0ef41Sopenharmony_ci  return js_descriptor.value();
15101cb0ef41Sopenharmony_ci}
15111cb0ef41Sopenharmony_ci
15121cb0ef41Sopenharmony_ciTNode<JSObject> ObjectBuiltinsAssembler::FromPropertyDetails(
15131cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<Object> raw_value, TNode<Word32T> details,
15141cb0ef41Sopenharmony_ci    Label* if_bailout) {
15151cb0ef41Sopenharmony_ci  TVARIABLE(JSObject, js_descriptor);
15161cb0ef41Sopenharmony_ci
15171cb0ef41Sopenharmony_ci  Label if_accessor_desc(this), if_data_desc(this), return_desc(this);
15181cb0ef41Sopenharmony_ci  BranchIfAccessorPair(raw_value, &if_accessor_desc, &if_data_desc);
15191cb0ef41Sopenharmony_ci
15201cb0ef41Sopenharmony_ci  BIND(&if_accessor_desc);
15211cb0ef41Sopenharmony_ci  {
15221cb0ef41Sopenharmony_ci    TNode<AccessorPair> accessor_pair_value = CAST(raw_value);
15231cb0ef41Sopenharmony_ci    TNode<HeapObject> getter = LoadObjectField<HeapObject>(
15241cb0ef41Sopenharmony_ci        accessor_pair_value, AccessorPair::kGetterOffset);
15251cb0ef41Sopenharmony_ci    TNode<HeapObject> setter = LoadObjectField<HeapObject>(
15261cb0ef41Sopenharmony_ci        accessor_pair_value, AccessorPair::kSetterOffset);
15271cb0ef41Sopenharmony_ci    js_descriptor = ConstructAccessorDescriptor(
15281cb0ef41Sopenharmony_ci        context, GetAccessorOrUndefined(getter, if_bailout),
15291cb0ef41Sopenharmony_ci        GetAccessorOrUndefined(setter, if_bailout),
15301cb0ef41Sopenharmony_ci        IsNotSetWord32(details, PropertyDetails::kAttributesDontEnumMask),
15311cb0ef41Sopenharmony_ci        IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask));
15321cb0ef41Sopenharmony_ci    Goto(&return_desc);
15331cb0ef41Sopenharmony_ci  }
15341cb0ef41Sopenharmony_ci
15351cb0ef41Sopenharmony_ci  BIND(&if_data_desc);
15361cb0ef41Sopenharmony_ci  {
15371cb0ef41Sopenharmony_ci    js_descriptor = ConstructDataDescriptor(
15381cb0ef41Sopenharmony_ci        context, raw_value,
15391cb0ef41Sopenharmony_ci        IsNotSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
15401cb0ef41Sopenharmony_ci        IsNotSetWord32(details, PropertyDetails::kAttributesDontEnumMask),
15411cb0ef41Sopenharmony_ci        IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask));
15421cb0ef41Sopenharmony_ci    Goto(&return_desc);
15431cb0ef41Sopenharmony_ci  }
15441cb0ef41Sopenharmony_ci
15451cb0ef41Sopenharmony_ci  BIND(&return_desc);
15461cb0ef41Sopenharmony_ci  return js_descriptor.value();
15471cb0ef41Sopenharmony_ci}
15481cb0ef41Sopenharmony_ci
15491cb0ef41Sopenharmony_ciTNode<HeapObject> ObjectBuiltinsAssembler::GetAccessorOrUndefined(
15501cb0ef41Sopenharmony_ci    TNode<HeapObject> accessor, Label* if_bailout) {
15511cb0ef41Sopenharmony_ci  Label bind_undefined(this, Label::kDeferred), return_result(this);
15521cb0ef41Sopenharmony_ci  TVARIABLE(HeapObject, result);
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_ci  GotoIf(IsNull(accessor), &bind_undefined);
15551cb0ef41Sopenharmony_ci  result = accessor;
15561cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(accessor);
15571cb0ef41Sopenharmony_ci  // TODO(ishell): probe template instantiations cache.
15581cb0ef41Sopenharmony_ci  GotoIf(IsFunctionTemplateInfoMap(map), if_bailout);
15591cb0ef41Sopenharmony_ci  Goto(&return_result);
15601cb0ef41Sopenharmony_ci
15611cb0ef41Sopenharmony_ci  BIND(&bind_undefined);
15621cb0ef41Sopenharmony_ci  result = UndefinedConstant();
15631cb0ef41Sopenharmony_ci  Goto(&return_result);
15641cb0ef41Sopenharmony_ci
15651cb0ef41Sopenharmony_ci  BIND(&return_result);
15661cb0ef41Sopenharmony_ci  return result.value();
15671cb0ef41Sopenharmony_ci}
15681cb0ef41Sopenharmony_ci}  // namespace internal
15691cb0ef41Sopenharmony_ci}  // namespace v8
1570