5 #ifndef V8_OBJECTS_JS_OBJECTS_INL_H_ 6 #define V8_OBJECTS_JS_OBJECTS_INL_H_ 8 #include "src/objects/js-objects.h" 10 #include "src/feedback-vector.h" 11 #include "src/heap/heap-write-barrier.h" 13 #include "src/lookup-inl.h" 14 #include "src/objects/embedder-data-slot-inl.h" 15 #include "src/objects/property-array-inl.h" 16 #include "src/objects/shared-function-info.h" 17 #include "src/objects/slots.h" 18 #include "src/objects/smi-inl.h" 19 #include "src/prototype.h" 22 #include "src/objects/object-macros.h" 27 CAST_ACCESSOR(JSAsyncFromSyncIterator)
28 CAST_ACCESSOR(JSBoundFunction)
29 CAST_ACCESSOR(JSDataView)
31 CAST_ACCESSOR(JSFunction)
32 CAST_ACCESSOR(JSGlobalObject)
33 CAST_ACCESSOR(JSGlobalProxy)
34 CAST_ACCESSOR(JSMessageObject)
35 CAST_ACCESSOR(JSObject)
36 CAST_ACCESSOR(JSReceiver)
37 CAST_ACCESSOR(JSStringIterator)
38 CAST_ACCESSOR(JSValue)
40 MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate,
41 Handle<JSReceiver> receiver,
43 LookupIterator it(isolate, receiver, name, receiver);
44 if (!it.IsFound())
return it.factory()->undefined_value();
45 return Object::GetProperty(&it);
48 MaybeHandle<Object> JSReceiver::GetElement(Isolate* isolate,
49 Handle<JSReceiver> receiver,
51 LookupIterator it(isolate, receiver, index, receiver);
52 if (!it.IsFound())
return it.factory()->undefined_value();
53 return Object::GetProperty(&it);
56 Handle<Object> JSReceiver::GetDataProperty(Handle<JSReceiver>
object,
58 LookupIterator it(
object, name,
object,
59 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
60 if (!it.IsFound())
return it.factory()->undefined_value();
61 return GetDataProperty(&it);
64 MaybeHandle<Object> JSReceiver::GetPrototype(Isolate* isolate,
65 Handle<JSReceiver> receiver) {
67 DCHECK(!receiver->IsAccessCheckNeeded() || receiver->IsJSObject());
68 PrototypeIterator iter(isolate, receiver, kStartAtReceiver,
69 PrototypeIterator::END_AT_NON_HIDDEN);
71 if (!iter.AdvanceFollowingProxies())
return MaybeHandle<Object>();
72 }
while (!iter.IsAtEnd());
73 return PrototypeIterator::GetCurrent(iter);
76 MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate,
77 Handle<JSReceiver> receiver,
79 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
80 return GetProperty(isolate, receiver, str);
84 V8_WARN_UNUSED_RESULT MaybeHandle<FixedArray> JSReceiver::OwnPropertyKeys(
85 Handle<JSReceiver>
object) {
86 return KeyAccumulator::GetKeys(
object, KeyCollectionMode::kOwnOnly,
88 GetKeysConversion::kConvertToString);
91 bool JSObject::PrototypeHasNoElements(Isolate* isolate, JSObject*
object) {
92 DisallowHeapAllocation no_gc;
93 HeapObject* prototype = HeapObject::cast(object->map()->prototype());
94 ReadOnlyRoots roots(isolate);
95 HeapObject* null = roots.null_value();
96 FixedArrayBase empty_fixed_array = roots.empty_fixed_array();
97 FixedArrayBase empty_slow_element_dictionary =
98 roots.empty_slow_element_dictionary();
99 while (prototype != null) {
100 Map map = prototype->map();
101 if (map->IsCustomElementsReceiverMap())
return false;
102 FixedArrayBase elements = JSObject::cast(prototype)->elements();
103 if (elements != empty_fixed_array &&
104 elements != empty_slow_element_dictionary) {
107 prototype = HeapObject::cast(map->prototype());
112 ACCESSORS(JSReceiver, raw_properties_or_hash, Object, kPropertiesOrHashOffset)
114 FixedArrayBase JSObject::elements()
const {
115 Object* array = READ_FIELD(
this, kElementsOffset);
116 return FixedArrayBase::cast(array);
119 void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject>
object) {
120 JSObject::ValidateElements(*
object);
121 ElementsKind elements_kind =
object->map()->elements_kind();
122 if (!IsObjectElementsKind(elements_kind)) {
123 if (IsHoleyElementsKind(elements_kind)) {
124 TransitionElementsKind(
object, HOLEY_ELEMENTS);
126 TransitionElementsKind(
object, PACKED_ELEMENTS);
131 void JSObject::EnsureCanContainElements(Handle<JSObject>
object,
133 EnsureElementsMode mode) {
134 ElementsKind current_kind =
object->GetElementsKind();
135 ElementsKind target_kind = current_kind;
137 DisallowHeapAllocation no_allocation;
138 DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
139 bool is_holey = IsHoleyElementsKind(current_kind);
140 if (current_kind == HOLEY_ELEMENTS)
return;
141 Object* the_hole =
object->GetReadOnlyRoots().the_hole_value();
143 Object* current = *objects;
144 if (current == the_hole) {
146 target_kind = GetHoleyElementsKind(target_kind);
147 }
else if (!current->IsSmi()) {
148 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
149 if (IsSmiElementsKind(target_kind)) {
151 target_kind = HOLEY_DOUBLE_ELEMENTS;
153 target_kind = PACKED_DOUBLE_ELEMENTS;
156 }
else if (is_holey) {
157 target_kind = HOLEY_ELEMENTS;
160 target_kind = PACKED_ELEMENTS;
165 if (target_kind != current_kind) {
166 TransitionElementsKind(
object, target_kind);
170 void JSObject::EnsureCanContainElements(Handle<JSObject>
object,
171 Handle<FixedArrayBase> elements,
173 EnsureElementsMode mode) {
174 ReadOnlyRoots roots =
object->GetReadOnlyRoots();
175 if (elements->map() != roots.fixed_double_array_map()) {
176 DCHECK(elements->map() == roots.fixed_array_map() ||
177 elements->map() == roots.fixed_cow_array_map());
178 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
179 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
182 Handle<FixedArray>::cast(elements)->GetFirstElementAddress();
183 EnsureCanContainElements(
object, objects, length, mode);
187 DCHECK(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
188 if (object->GetElementsKind() == HOLEY_SMI_ELEMENTS) {
189 TransitionElementsKind(
object, HOLEY_DOUBLE_ELEMENTS);
190 }
else if (object->GetElementsKind() == PACKED_SMI_ELEMENTS) {
191 Handle<FixedDoubleArray> double_array =
192 Handle<FixedDoubleArray>::cast(elements);
194 if (double_array->is_the_hole(
i)) {
195 TransitionElementsKind(
object, HOLEY_DOUBLE_ELEMENTS);
199 TransitionElementsKind(
object, PACKED_DOUBLE_ELEMENTS);
203 void JSObject::SetMapAndElements(Handle<JSObject>
object, Handle<Map> new_map,
204 Handle<FixedArrayBase> value) {
205 JSObject::MigrateToMap(
object, new_map);
206 DCHECK((object->map()->has_fast_smi_or_object_elements() ||
207 (*value ==
object->GetReadOnlyRoots().empty_fixed_array()) ||
208 object->map()->has_fast_string_wrapper_elements()) ==
209 (value->map() ==
object->GetReadOnlyRoots().fixed_array_map() ||
210 value->map() ==
object->GetReadOnlyRoots().fixed_cow_array_map()));
211 DCHECK((*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
212 (object->map()->has_fast_double_elements() ==
213 value->IsFixedDoubleArray()));
214 object->set_elements(*value);
217 void JSObject::set_elements(FixedArrayBase value, WriteBarrierMode mode) {
218 WRITE_FIELD(
this, kElementsOffset, value);
219 CONDITIONAL_WRITE_BARRIER(
this, kElementsOffset, value, mode);
222 void JSObject::initialize_elements() {
223 FixedArrayBase elements = map()->GetInitialElements();
224 WRITE_FIELD(
this, kElementsOffset, elements);
227 InterceptorInfo* JSObject::GetIndexedInterceptor() {
228 return map()->GetIndexedInterceptor();
231 InterceptorInfo* JSObject::GetNamedInterceptor() {
232 return map()->GetNamedInterceptor();
235 int JSObject::GetHeaderSize()
const {
return GetHeaderSize(map()); }
237 int JSObject::GetHeaderSize(
const Map map) {
241 InstanceType instance_type = map->instance_type();
242 return instance_type == JS_OBJECT_TYPE
243 ? JSObject::kHeaderSize
244 : GetHeaderSize(instance_type, map->has_prototype_slot());
248 int JSObject::GetEmbedderFieldCount(
const Map map) {
249 int instance_size = map->instance_size();
250 if (instance_size == kVariableSizeSentinel)
return 0;
254 return (((instance_size - GetHeaderSize(map)) >> kTaggedSizeLog2) -
255 map->GetInObjectProperties()) /
256 kEmbedderDataSlotSizeInTaggedSlots;
259 int JSObject::GetEmbedderFieldCount()
const {
260 return GetEmbedderFieldCount(map());
263 int JSObject::GetEmbedderFieldOffset(
int index) {
264 DCHECK(index < GetEmbedderFieldCount() && index >= 0);
268 return GetHeaderSize() + (kEmbedderDataSlotSize * index);
271 Object* JSObject::GetEmbedderField(
int index) {
272 return EmbedderDataSlot(
this, index).load_tagged();
275 void JSObject::SetEmbedderField(
int index, Object* value) {
276 EmbedderDataSlot::store_tagged(
this, index, value);
279 void JSObject::SetEmbedderField(
int index, Smi value) {
280 EmbedderDataSlot(
this, index).store_smi(value);
283 bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
284 if (!FLAG_unbox_double_fields)
return false;
285 return map()->IsUnboxedDoubleField(index);
291 Object* JSObject::RawFastPropertyAt(FieldIndex index) {
292 DCHECK(!IsUnboxedDoubleField(index));
293 if (index.is_inobject()) {
294 return READ_FIELD(
this, index.offset());
296 return property_array()->get(index.outobject_array_index());
300 double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
301 DCHECK(IsUnboxedDoubleField(index));
302 return READ_DOUBLE_FIELD(
this, index.offset());
305 uint64_t JSObject::RawFastDoublePropertyAsBitsAt(FieldIndex index) {
306 DCHECK(IsUnboxedDoubleField(index));
307 return READ_UINT64_FIELD(
this, index.offset());
310 void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
311 if (index.is_inobject()) {
312 int offset = index.offset();
313 WRITE_FIELD(
this, offset, value);
314 WRITE_BARRIER(
this, offset, value);
316 property_array()->set(index.outobject_array_index(), value);
320 void JSObject::RawFastDoublePropertyAsBitsAtPut(FieldIndex index,
324 DCHECK_EQ(kDoubleSize, kTaggedSize);
325 Address field_addr = FIELD_ADDR(
this, index.offset());
326 base::Relaxed_Store(reinterpret_cast<base::AtomicWord*>(field_addr),
327 static_cast<base::AtomicWord>(bits));
330 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
331 if (IsUnboxedDoubleField(index)) {
332 DCHECK(value->IsMutableHeapNumber());
334 RawFastDoublePropertyAsBitsAtPut(
335 index, MutableHeapNumber::cast(value)->value_as_bits());
337 RawFastPropertyAtPut(index, value);
341 void JSObject::WriteToField(
int descriptor, PropertyDetails details,
343 DCHECK_EQ(kField, details.location());
344 DCHECK_EQ(kData, details.kind());
345 DisallowHeapAllocation no_gc;
346 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
347 if (details.representation().IsDouble()) {
349 if (value->IsUninitialized()) {
357 if (value->IsSmi()) {
358 bits = bit_cast<uint64_t>(
static_cast<double>(Smi::ToInt(value)));
360 DCHECK(value->IsHeapNumber());
361 bits = HeapNumber::cast(value)->value_as_bits();
363 if (IsUnboxedDoubleField(index)) {
364 RawFastDoublePropertyAsBitsAtPut(index, bits);
366 auto box = MutableHeapNumber::cast(RawFastPropertyAt(index));
367 box->set_value_as_bits(bits);
370 RawFastPropertyAtPut(index, value);
374 int JSObject::GetInObjectPropertyOffset(
int index) {
375 return map()->GetInObjectPropertyOffset(index);
378 Object* JSObject::InObjectPropertyAt(
int index) {
379 int offset = GetInObjectPropertyOffset(index);
380 return READ_FIELD(
this, offset);
383 Object* JSObject::InObjectPropertyAtPut(
int index, Object* value,
384 WriteBarrierMode mode) {
386 int offset = GetInObjectPropertyOffset(index);
387 WRITE_FIELD(
this, offset, value);
388 CONDITIONAL_WRITE_BARRIER(
this, offset, value, mode);
392 void JSObject::InitializeBody(Map map,
int start_offset,
393 Object* pre_allocated_value,
394 Object* filler_value) {
395 DCHECK(!filler_value->IsHeapObject() || !Heap::InNewSpace(filler_value));
396 DCHECK(!pre_allocated_value->IsHeapObject() ||
397 !Heap::InNewSpace(pre_allocated_value));
398 int size = map->instance_size();
399 int offset = start_offset;
400 if (filler_value != pre_allocated_value) {
401 int end_of_pre_allocated_offset =
402 size - (map->UnusedPropertyFields() * kTaggedSize);
403 DCHECK_LE(kHeaderSize, end_of_pre_allocated_offset);
404 while (offset < end_of_pre_allocated_offset) {
405 WRITE_FIELD(
this, offset, pre_allocated_value);
406 offset += kTaggedSize;
409 while (offset < size) {
410 WRITE_FIELD(
this, offset, filler_value);
411 offset += kTaggedSize;
415 Object* JSBoundFunction::raw_bound_target_function()
const {
416 return READ_FIELD(
this, kBoundTargetFunctionOffset);
419 ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
420 kBoundTargetFunctionOffset)
421 ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
422 ACCESSORS2(JSBoundFunction, bound_arguments, FixedArray, kBoundArgumentsOffset)
424 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
425 ACCESSORS(JSFunction, feedback_cell, FeedbackCell, kFeedbackCellOffset)
427 ACCESSORS2(JSGlobalObject, native_context, Context, kNativeContextOffset)
428 ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
430 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
432 FeedbackVector* JSFunction::feedback_vector()
const {
433 DCHECK(has_feedback_vector());
434 return FeedbackVector::cast(feedback_cell()->value());
443 bool JSFunction::IsOptimized() {
444 return code()->kind() == Code::OPTIMIZED_FUNCTION &&
445 !code()->marked_for_deoptimization();
448 bool JSFunction::HasOptimizedCode() {
449 return IsOptimized() ||
450 (has_feedback_vector() && feedback_vector()->has_optimized_code() &&
451 !feedback_vector()->optimized_code()->marked_for_deoptimization());
454 bool JSFunction::HasOptimizationMarker() {
455 return has_feedback_vector() && feedback_vector()->has_optimization_marker();
458 void JSFunction::ClearOptimizationMarker() {
459 DCHECK(has_feedback_vector());
460 feedback_vector()->ClearOptimizationMarker();
465 bool JSFunction::IsInterpreted() {
466 return code()->is_interpreter_trampoline_builtin() ||
467 (code()->kind() == Code::OPTIMIZED_FUNCTION &&
468 code()->marked_for_deoptimization());
471 bool JSFunction::ChecksOptimizationMarker() {
472 return code()->checks_optimization_marker();
475 bool JSFunction::IsMarkedForOptimization() {
476 return has_feedback_vector() && feedback_vector()->optimization_marker() ==
477 OptimizationMarker::kCompileOptimized;
480 bool JSFunction::IsMarkedForConcurrentOptimization() {
481 return has_feedback_vector() &&
482 feedback_vector()->optimization_marker() ==
483 OptimizationMarker::kCompileOptimizedConcurrent;
486 bool JSFunction::IsInOptimizationQueue() {
487 return has_feedback_vector() && feedback_vector()->optimization_marker() ==
488 OptimizationMarker::kInOptimizationQueue;
491 void JSFunction::CompleteInobjectSlackTrackingIfActive() {
492 if (!has_prototype_slot())
return;
493 if (has_initial_map() && initial_map()->IsInobjectSlackTrackingInProgress()) {
494 initial_map()->CompleteInobjectSlackTracking(GetIsolate());
498 AbstractCode JSFunction::abstract_code() {
499 if (IsInterpreted()) {
500 return AbstractCode::cast(shared()->GetBytecodeArray());
502 return AbstractCode::cast(code());
506 Code JSFunction::code() {
return Code::cast(READ_FIELD(
this, kCodeOffset)); }
508 void JSFunction::set_code(Code value) {
509 DCHECK(!Heap::InNewSpace(value));
510 WRITE_FIELD(
this, kCodeOffset, value);
511 MarkingBarrier(
this, HeapObject::RawField(
this, kCodeOffset), value);
514 void JSFunction::set_code_no_write_barrier(Code value) {
515 DCHECK(!Heap::InNewSpace(value));
516 WRITE_FIELD(
this, kCodeOffset, value);
519 void JSFunction::ClearOptimizedCodeSlot(
const char* reason) {
520 if (has_feedback_vector() && feedback_vector()->has_optimized_code()) {
521 if (FLAG_trace_opt) {
522 PrintF(
"[evicting entry from optimizing code feedback slot (%s) for ",
527 feedback_vector()->ClearOptimizedCode();
531 void JSFunction::SetOptimizationMarker(OptimizationMarker marker) {
532 DCHECK(has_feedback_vector());
533 DCHECK(ChecksOptimizationMarker());
534 DCHECK(!HasOptimizedCode());
536 feedback_vector()->SetOptimizationMarker(marker);
539 bool JSFunction::has_feedback_vector()
const {
540 return !feedback_cell()->value()->IsUndefined();
543 Context JSFunction::context() {
544 return Context::cast(READ_FIELD(
this, kContextOffset));
547 bool JSFunction::has_context()
const {
548 return READ_FIELD(
this, kContextOffset)->IsContext();
551 JSGlobalProxy* JSFunction::global_proxy() {
return context()->global_proxy(); }
553 Context JSFunction::native_context() {
return context()->native_context(); }
555 void JSFunction::set_context(Object* value) {
556 DCHECK(value->IsUndefined() || value->IsContext());
557 WRITE_FIELD(
this, kContextOffset, value);
558 WRITE_BARRIER(
this, kContextOffset, value);
561 ACCESSORS_CHECKED(JSFunction, prototype_or_initial_map, Object,
562 kPrototypeOrInitialMapOffset, map()->has_prototype_slot())
564 bool JSFunction::has_prototype_slot()
const {
565 return map()->has_prototype_slot();
568 Map JSFunction::initial_map() {
return Map::cast(prototype_or_initial_map()); }
570 bool JSFunction::has_initial_map() {
571 DCHECK(has_prototype_slot());
572 return prototype_or_initial_map()->IsMap();
575 bool JSFunction::has_instance_prototype() {
576 DCHECK(has_prototype_slot());
577 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
580 bool JSFunction::has_prototype() {
581 DCHECK(has_prototype_slot());
582 return map()->has_non_instance_prototype() || has_instance_prototype();
585 bool JSFunction::has_prototype_property() {
586 return (has_prototype_slot() && IsConstructor()) ||
587 IsGeneratorFunction(shared()->kind());
590 bool JSFunction::PrototypeRequiresRuntimeLookup() {
591 return !has_prototype_property() || map()->has_non_instance_prototype();
594 Object* JSFunction::instance_prototype() {
595 DCHECK(has_instance_prototype());
596 if (has_initial_map())
return initial_map()->prototype();
599 return prototype_or_initial_map();
602 Object* JSFunction::prototype() {
603 DCHECK(has_prototype());
606 if (map()->has_non_instance_prototype()) {
607 Object* prototype = map()->GetConstructor();
609 DCHECK(!prototype->IsMap());
610 DCHECK(!prototype->IsFunctionTemplateInfo());
613 return instance_prototype();
616 bool JSFunction::is_compiled() {
617 return code()->builtin_index() != Builtins::kCompileLazy;
620 ACCESSORS(JSValue, value, Object, kValueOffset)
622 ACCESSORS(JSDate, value, Object, kValueOffset)
623 ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
624 ACCESSORS(JSDate, year, Object, kYearOffset)
625 ACCESSORS(JSDate, month, Object, kMonthOffset)
626 ACCESSORS(JSDate, day, Object, kDayOffset)
627 ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
628 ACCESSORS(JSDate, hour, Object, kHourOffset)
629 ACCESSORS(JSDate, min, Object, kMinOffset)
630 ACCESSORS(JSDate, sec, Object, kSecOffset)
632 MessageTemplate JSMessageObject::type()
const {
633 Object* value = READ_FIELD(
this, kTypeOffset);
634 return MessageTemplateFromInt(Smi::ToInt(value));
636 void JSMessageObject::set_type(MessageTemplate value) {
637 WRITE_FIELD(
this, kTypeOffset, Smi::FromInt(static_cast<int>(value)));
639 ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
640 ACCESSORS(JSMessageObject, script, Script, kScriptOffset)
641 ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
642 SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
643 SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
644 SMI_ACCESSORS(JSMessageObject, error_level, kErrorLevelOffset)
646 ElementsKind JSObject::GetElementsKind()
const {
647 ElementsKind kind = map()->elements_kind();
648 #if VERIFY_HEAP && DEBUG 649 FixedArrayBase fixed_array =
650 FixedArrayBase::unchecked_cast(READ_FIELD(
this, kElementsOffset));
654 if (ElementsAreSafeToExamine()) {
655 Map map = fixed_array->map();
656 if (IsSmiOrObjectElementsKind(kind)) {
657 DCHECK(map == GetReadOnlyRoots().fixed_array_map() ||
658 map == GetReadOnlyRoots().fixed_cow_array_map());
659 }
else if (IsDoubleElementsKind(kind)) {
660 DCHECK(fixed_array->IsFixedDoubleArray() ||
661 fixed_array == GetReadOnlyRoots().empty_fixed_array());
662 }
else if (kind == DICTIONARY_ELEMENTS) {
663 DCHECK(fixed_array->IsFixedArray());
664 DCHECK(fixed_array->IsDictionary());
666 DCHECK(kind > DICTIONARY_ELEMENTS);
668 DCHECK(!IsSloppyArgumentsElementsKind(kind) ||
669 (elements()->IsFixedArray() && elements()->length() >= 2));
675 bool JSObject::HasObjectElements() {
676 return IsObjectElementsKind(GetElementsKind());
679 bool JSObject::HasSmiElements() {
return IsSmiElementsKind(GetElementsKind()); }
681 bool JSObject::HasSmiOrObjectElements() {
682 return IsSmiOrObjectElementsKind(GetElementsKind());
685 bool JSObject::HasDoubleElements() {
686 return IsDoubleElementsKind(GetElementsKind());
689 bool JSObject::HasHoleyElements() {
690 return IsHoleyElementsKind(GetElementsKind());
693 bool JSObject::HasFastElements() {
694 return IsFastElementsKind(GetElementsKind());
697 bool JSObject::HasFastPackedElements() {
698 return IsFastPackedElementsKind(GetElementsKind());
701 bool JSObject::HasDictionaryElements() {
702 return GetElementsKind() == DICTIONARY_ELEMENTS;
705 bool JSObject::HasFastArgumentsElements() {
706 return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
709 bool JSObject::HasSlowArgumentsElements() {
710 return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
713 bool JSObject::HasSloppyArgumentsElements() {
714 return IsSloppyArgumentsElementsKind(GetElementsKind());
717 bool JSObject::HasStringWrapperElements() {
718 return IsStringWrapperElementsKind(GetElementsKind());
721 bool JSObject::HasFastStringWrapperElements() {
722 return GetElementsKind() == FAST_STRING_WRAPPER_ELEMENTS;
725 bool JSObject::HasSlowStringWrapperElements() {
726 return GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS;
729 bool JSObject::HasFixedTypedArrayElements() {
730 DCHECK(!elements().is_null());
731 return map()->has_fixed_typed_array_elements();
734 #define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype) \ 735 bool JSObject::HasFixed##Type##Elements() { \ 736 FixedArrayBase array = elements(); \ 737 return array->map()->instance_type() == FIXED_##TYPE##_ARRAY_TYPE; \ 740 TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
742 #undef FIXED_TYPED_ELEMENTS_CHECK 744 bool JSObject::HasNamedInterceptor() {
return map()->has_named_interceptor(); }
746 bool JSObject::HasIndexedInterceptor() {
747 return map()->has_indexed_interceptor();
750 void JSGlobalObject::set_global_dictionary(GlobalDictionary dictionary) {
751 DCHECK(IsJSGlobalObject());
752 set_raw_properties_or_hash(dictionary);
755 GlobalDictionary JSGlobalObject::global_dictionary() {
756 DCHECK(!HasFastProperties());
757 DCHECK(IsJSGlobalObject());
758 return GlobalDictionary::cast(raw_properties_or_hash());
761 NumberDictionary JSObject::element_dictionary() {
762 DCHECK(HasDictionaryElements() || HasSlowStringWrapperElements());
763 return NumberDictionary::cast(elements());
766 void JSReceiver::initialize_properties() {
767 ReadOnlyRoots roots = GetReadOnlyRoots();
768 DCHECK(!Heap::InNewSpace(roots.empty_fixed_array()));
769 DCHECK(!Heap::InNewSpace(roots.empty_property_dictionary()));
770 if (map()->is_dictionary_map()) {
771 WRITE_FIELD(
this, kPropertiesOrHashOffset,
772 roots.empty_property_dictionary());
774 WRITE_FIELD(
this, kPropertiesOrHashOffset, roots.empty_fixed_array());
778 bool JSReceiver::HasFastProperties()
const {
780 raw_properties_or_hash()->IsSmi() ||
781 (raw_properties_or_hash()->IsDictionary() == map()->is_dictionary_map()));
782 return !map()->is_dictionary_map();
785 NameDictionary JSReceiver::property_dictionary()
const {
786 DCHECK(!IsJSGlobalObject());
787 DCHECK(!HasFastProperties());
789 Object* prop = raw_properties_or_hash();
791 return GetReadOnlyRoots().empty_property_dictionary();
794 return NameDictionary::cast(prop);
799 PropertyArray JSReceiver::property_array()
const {
800 DCHECK(HasFastProperties());
802 Object* prop = raw_properties_or_hash();
803 if (prop->IsSmi() || prop == GetReadOnlyRoots().empty_fixed_array()) {
804 return GetReadOnlyRoots().empty_property_array();
807 return PropertyArray::cast(prop);
810 Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver>
object,
812 LookupIterator it = LookupIterator::PropertyOrElement(object->GetIsolate(),
813 object, name, object);
814 return HasProperty(&it);
817 Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver>
object,
819 if (object->IsJSModuleNamespace())
return Just(
false);
821 if (object->IsJSObject()) {
822 LookupIterator it(object->GetIsolate(), object, index, object,
823 LookupIterator::OWN);
824 return HasProperty(&it);
827 Maybe<PropertyAttributes> attributes =
828 JSReceiver::GetOwnPropertyAttributes(
object, index);
829 MAYBE_RETURN(attributes, Nothing<bool>());
830 return Just(attributes.FromJust() != ABSENT);
833 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
834 Handle<JSReceiver>
object, Handle<Name> name) {
835 LookupIterator it = LookupIterator::PropertyOrElement(object->GetIsolate(),
836 object, name, object);
837 return GetPropertyAttributes(&it);
840 Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
841 Handle<JSReceiver>
object, Handle<Name> name) {
842 LookupIterator it = LookupIterator::PropertyOrElement(
843 object->GetIsolate(), object, name, object, LookupIterator::OWN);
844 return GetPropertyAttributes(&it);
847 Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
848 Handle<JSReceiver>
object,
uint32_t index) {
849 LookupIterator it(object->GetIsolate(), object, index, object,
850 LookupIterator::OWN);
851 return GetPropertyAttributes(&it);
854 Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver>
object,
uint32_t index) {
855 LookupIterator it(object->GetIsolate(), object, index, object);
856 return HasProperty(&it);
859 Maybe<PropertyAttributes> JSReceiver::GetElementAttributes(
860 Handle<JSReceiver>
object,
uint32_t index) {
861 Isolate* isolate =
object->GetIsolate();
862 LookupIterator it(isolate,
object, index,
object);
863 return GetPropertyAttributes(&it);
866 Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttributes(
867 Handle<JSReceiver>
object,
uint32_t index) {
868 Isolate* isolate =
object->GetIsolate();
869 LookupIterator it(isolate,
object, index,
object, LookupIterator::OWN);
870 return GetPropertyAttributes(&it);
873 bool JSGlobalObject::IsDetached() {
874 return JSGlobalProxy::cast(global_proxy())->IsDetachedFrom(
this);
877 bool JSGlobalProxy::IsDetachedFrom(JSGlobalObject* global)
const {
878 const PrototypeIterator iter(this->GetIsolate(),
879 const_cast<JSGlobalProxy*>(
this));
880 return iter.GetCurrent() != global;
883 inline int JSGlobalProxy::SizeWithEmbedderFields(
int embedder_field_count) {
884 DCHECK_GE(embedder_field_count, 0);
885 return kSize + embedder_field_count * kEmbedderDataSlotSize;
888 ACCESSORS(JSIteratorResult, value, Object, kValueOffset)
889 ACCESSORS(JSIteratorResult, done, Object, kDoneOffset)
891 ACCESSORS(JSAsyncFromSyncIterator, sync_iterator, JSReceiver,
893 ACCESSORS(JSAsyncFromSyncIterator, next, Object, kNextOffset)
895 ACCESSORS2(JSStringIterator,
string, String, kStringOffset)
896 SMI_ACCESSORS(JSStringIterator, index, kNextIndexOffset)
901 #include "src/objects/object-macros-undef.h" 903 #endif // V8_OBJECTS_JS_OBJECTS_INL_H_