v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
objects.cc
Go to the documentation of this file.
1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <algorithm>
8#include <cmath>
9#include <memory>
10#include <optional>
11#include <sstream>
12#include <vector>
13
15#include "src/api/api-natives.h"
16#include "src/api/api.h"
17#include "src/ast/ast.h"
18#include "src/ast/scopes.h"
19#include "src/base/bits.h"
21#include "src/base/logging.h"
28#include "src/common/globals.h"
30#include "src/date/date.h"
31#include "src/debug/debug.h"
42#include "src/heap/heap-inl.h"
45#include "src/ic/ic.h"
48#include "src/logging/log.h"
54#include "src/objects/bigint.h"
66#include "src/objects/foreign.h"
80#include "src/objects/keys.h"
83#include "src/objects/map-inl.h"
85#include "src/objects/map.h"
92#include "src/objects/promise.h"
104#include "src/regexp/regexp.h"
105#include "src/roots/roots.h"
113#include "src/utils/hex-format.h"
115#include "src/utils/ostreams.h"
116#include "src/utils/sha-256.h"
117#include "src/utils/utils-inl.h"
118#include "src/zone/zone.h"
119
120#if V8_ENABLE_WEBASSEMBLY
122#endif // V8_ENABLE_WEBASSEMBLY
123
124#ifdef V8_INTL_SUPPORT
136#endif // V8_INTL_SUPPORT
137
138namespace v8::internal {
139
141 if (should_throw.IsJust()) return should_throw.FromJust();
142
143 LanguageMode mode = isolate->context()->scope_info()->language_mode();
144 if (mode == LanguageMode::kStrict) return kThrowOnError;
145
146 for (StackFrameIterator it(isolate, isolate->thread_local_top()); !it.done();
147 it.Advance()) {
148 if (!it.frame()->is_javascript()) continue;
149
150 // Get the language mode from closure.
151 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(it.frame());
152 std::vector<Tagged<SharedFunctionInfo>> functions;
153 js_frame->GetFunctions(&functions);
154 LanguageMode closure_language_mode = functions.back()->language_mode();
155 if (closure_language_mode > mode) {
156 mode = closure_language_mode;
157 }
158 break;
159 }
160
161 return is_sloppy(mode) ? kDontThrow : kThrowOnError;
162}
163
165 switch (op) {
166 case Operation::kLessThan:
168 case Operation::kLessThanOrEqual:
171 case Operation::kGreaterThan:
173 case Operation::kGreaterThanOrEqual:
176 default:
177 break;
178 }
179 UNREACHABLE();
180}
181
182std::string ToString(InstanceType instance_type) {
183 if (InstanceTypeChecker::IsJSApiObject(instance_type)) {
184 std::stringstream ss;
185 ss << "[api object] "
186 << static_cast<int16_t>(instance_type) -
187 i::Internals::kFirstJSApiObjectType;
188 return ss.str();
189 }
190 switch (instance_type) {
191#define WRITE_TYPE(TYPE) \
192 case TYPE: \
193 return #TYPE;
195#undef WRITE_TYPE
196 }
197
198 std::stringstream ss;
199 ss << "[unknown instance type " << static_cast<int16_t>(instance_type) << "]";
200 return ss.str();
201}
202
203std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
204 return os << ToString(instance_type);
205}
206
207std::ostream& operator<<(std::ostream& os, PropertyCellType type) {
208 switch (type) {
210 return os << "Undefined";
212 return os << "Constant";
214 return os << "ConstantType";
216 return os << "Mutable";
218 return os << "InTransition";
219 }
220 UNREACHABLE();
221}
222
223// static
225 Isolate* isolate,
226 Representation representation) {
227 if (representation.IsNone()) return FieldType::None(isolate);
228 if (v8_flags.track_field_types) {
229 if (representation.IsHeapObject() && IsHeapObject(obj)) {
230 // We can track only JavaScript objects with stable maps.
231 DirectHandle<Map> map(Cast<HeapObject>(obj)->map(), isolate);
232 if (map->is_stable() && IsJSReceiverMap(*map)) {
233 return FieldType::Class(map, isolate);
234 }
235 }
236 }
237 return FieldType::Any(isolate);
238}
239
241 Isolate* isolate, Handle<UnionOf<JSAny, Hole>> object,
242 Representation representation) {
243 if (!representation.IsDouble()) return object;
244 Handle<HeapNumber> result = isolate->factory()->NewHeapNumberWithHoleNaN();
245 if (IsUninitialized(*object, isolate)) {
246 result->set_value_as_bits(kHoleNanInt64);
247 } else if (IsHeapNumber(*object)) {
248 // Ensure that all bits of the double value are preserved.
249 result->set_value_as_bits(Cast<HeapNumber>(*object)->value_as_bits());
250 } else {
251 result->set_value(Cast<Smi>(*object).value());
252 }
253 return result;
254}
255
256template <AllocationType allocation_type, typename IsolateT>
258 Representation representation) {
259 DCHECK(!IsUninitialized(*object, isolate));
260 if (!representation.IsDouble()) {
261 DCHECK(Object::FitsRepresentation(*object, representation));
262 return object;
263 }
264 return isolate->factory()->template NewHeapNumberFromBits<allocation_type>(
265 Cast<HeapNumber>(*object)->value_as_bits());
266}
267
268template Handle<JSAny> Object::WrapForRead<AllocationType::kYoung>(
269 Isolate* isolate, Handle<JSAny> object, Representation representation);
270template Handle<JSAny> Object::WrapForRead<AllocationType::kOld>(
271 LocalIsolate* isolate, Handle<JSAny> object, Representation representation);
272
275 const char* method_name) {
276 DCHECK(!IsJSReceiver(*object)); // Use ToObject() for fast path.
277 DirectHandle<Context> native_context = isolate->native_context();
278 DirectHandle<JSFunction> constructor;
279 if (IsSmi(*object)) {
280 constructor = direct_handle(native_context->number_function(), isolate);
281 } else {
282 int constructor_function_index =
283 Cast<HeapObject>(object)->map()->GetConstructorFunctionIndex();
284 if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
285 if (method_name != nullptr) {
287 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
288 isolate->factory()->NewStringFromAsciiChecked(
289 method_name)));
290 }
291 THROW_NEW_ERROR(isolate,
292 NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
293 }
294 constructor = direct_handle(
295 Cast<JSFunction>(native_context->get(constructor_function_index)),
296 isolate);
297 }
298 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
299 Cast<JSPrimitiveWrapper>(result)->set_value(Cast<JSAny>(*object));
300 return result;
301}
302
303// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
304// static
306 Isolate* isolate, DirectHandle<Object> object) {
307 if (IsJSReceiver(*object)) return Cast<JSReceiver>(object);
308 if (IsNullOrUndefined(*object, isolate)) {
309 return isolate->global_proxy();
310 }
311 return Object::ToObject(isolate, object);
312}
313
314// static
315
316template <template <typename> typename HandleType>
317 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
318typename HandleType<Number>::MaybeType Object::ConvertToNumber(
319 Isolate* isolate, HandleType<Object> input) {
320 while (true) {
321 if (IsNumber(*input)) {
322 return Cast<Number>(input);
323 }
324 if (IsString(*input)) {
325 return String::ToNumber(isolate, Cast<String>(input));
326 }
327 if (IsOddball(*input)) {
328 return Oddball::ToNumber(isolate, Cast<Oddball>(input));
329 }
330 if (IsSymbol(*input)) {
331 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber));
332 }
333 if (IsBigInt(*input)) {
334 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kBigIntToNumber));
335 }
337 isolate, input,
340 }
341}
342
344 Isolate* isolate, DirectHandle<Object> input);
346 Isolate* isolate, IndirectHandle<Object> input);
347
348// static
349template <template <typename> typename HandleType>
350 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
351typename HandleType<Numeric>::MaybeType Object::ConvertToNumeric(
352 Isolate* isolate, HandleType<Object> input) {
353 while (true) {
354 if (IsNumber(*input)) {
355 return Cast<Number>(input);
356 }
357 if (IsString(*input)) {
358 return String::ToNumber(isolate, Cast<String>(input));
359 }
360 if (IsOddball(*input)) {
361 return Oddball::ToNumber(isolate, Cast<Oddball>(input));
362 }
363 if (IsSymbol(*input)) {
364 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber));
365 }
366 if (IsBigInt(*input)) {
367 return Cast<BigInt>(input);
368 }
370 isolate, input,
373 }
374}
375
377 Isolate* isolate, DirectHandle<Object> input);
380
381// static
382template <template <typename> typename HandleType>
383 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
384typename HandleType<Number>::MaybeType Object::ConvertToInteger(
385 Isolate* isolate, HandleType<Object> input) {
386 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input));
387 if (IsSmi(*input)) return Cast<Smi>(input);
388 return isolate->factory()->NewNumber(
389 DoubleToInteger(Cast<HeapNumber>(*input)->value()));
390}
391
392template V8_EXPORT_PRIVATE MaybeDirectHandle<Number> Object::ConvertToInteger(
393 Isolate* isolate, DirectHandle<Object> input);
394template V8_EXPORT_PRIVATE MaybeIndirectHandle<Number> Object::ConvertToInteger(
395 Isolate* isolate, IndirectHandle<Object> input);
396
397// static
398template <template <typename> typename HandleType>
399 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
400typename HandleType<Number>::MaybeType Object::ConvertToInt32(
401 Isolate* isolate, HandleType<Object> input) {
402 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input));
403 if (IsSmi(*input)) return Cast<Smi>(input);
404 return isolate->factory()->NewNumberFromInt(
405 DoubleToInt32(Cast<HeapNumber>(*input)->value()));
406}
407
409 Isolate* isolate, DirectHandle<Object> input);
411 Isolate* isolate, IndirectHandle<Object> input);
412
413// static
414template <template <typename> typename HandleType>
415 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
416typename HandleType<Number>::MaybeType Object::ConvertToUint32(
417 Isolate* isolate, HandleType<Object> input) {
418 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ConvertToNumber(isolate, input));
419 if (IsSmi(*input))
420 return typename HandleType<Number>::MaybeType(
421 Smi::ToUint32Smi(Cast<Smi>(*input)), isolate);
422 return isolate->factory()->NewNumberFromUint(
423 DoubleToUint32(Cast<HeapNumber>(*input)->value()));
424}
425
427 Isolate* isolate, DirectHandle<Object> input);
429 Isolate* isolate, IndirectHandle<Object> input);
430
431// static
432template <template <typename> typename HandleType>
433 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
434typename HandleType<Name>::MaybeType Object::ConvertToName(
435 Isolate* isolate, HandleType<Object> input) {
437 isolate, input,
439 if (IsName(*input)) return Cast<Name>(input);
440 return ToString(isolate, input);
441}
442
444 Isolate* isolate, DirectHandle<Object> input);
446 Isolate* isolate, IndirectHandle<Object> input);
447
448// ES6 7.1.14
449// static
450template <template <typename> typename HandleType>
451 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
452typename HandleType<Object>::MaybeType Object::ConvertToPropertyKey(
453 Isolate* isolate, HandleType<Object> value) {
454 // 1. Let key be ToPrimitive(argument, hint String).
455 typename HandleType<Object>::MaybeType maybe_key =
457 // 2. ReturnIfAbrupt(key).
458 HandleType<Object> key;
459 if (!maybe_key.ToHandle(&key)) return key;
460 // 3. If Type(key) is Symbol, then return key.
461 if (IsSymbol(*key)) return key;
462 // 4. Return ToString(key).
463 // Extending spec'ed behavior, we'd be happy to return an element index.
464 if (IsSmi(*key)) return key;
465 if (IsHeapNumber(*key)) {
466 uint32_t uint_value;
467 if (Object::ToArrayLength(*value, &uint_value) &&
468 uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
469 return HandleType<Object>(Smi::FromInt(static_cast<int>(uint_value)),
470 isolate);
471 }
472 }
473 return Object::ToString(isolate, key);
474}
475
481// static
482template <template <typename> typename HandleType>
483 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
484typename HandleType<String>::MaybeType Object::ConvertToString(
485 Isolate* isolate, HandleType<Object> input) {
486 while (true) {
487 if (IsOddball(*input)) {
488 HandleType<String> result(Cast<Oddball>(input)->to_string(), isolate);
489 return result;
490 }
491 if (IsNumber(*input)) {
492 return isolate->factory()->NumberToString(input);
493 }
494 if (IsSymbol(*input)) {
495 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString));
496 }
497 if (IsBigInt(*input)) {
498 return BigInt::ToString(isolate, Cast<BigInt>(input));
499 }
500#if V8_ENABLE_WEBASSEMBLY
501 // We generally don't let the WasmNull escape into the JavaScript world,
502 // but some builtins may encounter it when called directly from Wasm code.
503 if (IsWasmNull(*input)) {
504 return isolate->factory()->null_string();
505 }
506#endif
508 isolate, input,
511 // The previous isString() check happened in Object::ToString and thus we
512 // put it at the end of the loop in this helper.
513 if (IsString(*input)) {
514 return Cast<String>(input);
515 }
516 }
517}
518
519template V8_EXPORT_PRIVATE MaybeDirectHandle<String> Object::ConvertToString(
520 Isolate* isolate, DirectHandle<Object> input);
521template V8_EXPORT_PRIVATE MaybeIndirectHandle<String> Object::ConvertToString(
522 Isolate* isolate, IndirectHandle<Object> input);
523
524namespace {
525
526bool IsErrorObject(Isolate* isolate, DirectHandle<Object> object) {
527 if (!IsJSObject(*object)) return false;
529 Cast<JSObject>(object));
530}
531
532DirectHandle<String> AsStringOrEmpty(Isolate* isolate,
533 DirectHandle<Object> object) {
534 return IsString(*object) ? Cast<String>(object)
535 : isolate->factory()->empty_string();
536}
537
538DirectHandle<String> NoSideEffectsErrorToString(
539 Isolate* isolate, DirectHandle<JSReceiver> error) {
540 DirectHandle<Name> name_key = isolate->factory()->name_string();
541 DirectHandle<Object> name =
542 JSReceiver::GetDataProperty(isolate, error, name_key);
543 DirectHandle<String> name_str = AsStringOrEmpty(isolate, name);
544
545 DirectHandle<Name> msg_key = isolate->factory()->message_string();
546 DirectHandle<Object> msg =
547 JSReceiver::GetDataProperty(isolate, error, msg_key);
548 DirectHandle<String> msg_str = AsStringOrEmpty(isolate, msg);
549
550 if (name_str->length() == 0) return msg_str;
551 if (msg_str->length() == 0) return name_str;
552
553 constexpr const char error_suffix[] = "<a very large string>";
554 constexpr uint32_t error_suffix_size = sizeof(error_suffix);
555 uint32_t suffix_size = std::min(error_suffix_size, msg_str->length());
556
557 IncrementalStringBuilder builder(isolate);
558 if (name_str->length() + suffix_size + 2 /* ": " */ > String::kMaxLength) {
559 constexpr const char connector[] = "... : ";
560 int connector_size = sizeof(connector);
561 DirectHandle<String> truncated_name =
562 isolate->factory()->NewProperSubString(
563 name_str, 0,
564 name_str->length() - error_suffix_size - connector_size);
565 builder.AppendString(truncated_name);
566 builder.AppendCStringLiteral(connector);
567 builder.AppendCStringLiteral(error_suffix);
568 } else {
569 builder.AppendString(name_str);
570 builder.AppendCStringLiteral(": ");
571 if (builder.Length() + msg_str->length() <= String::kMaxLength) {
572 builder.AppendString(msg_str);
573 } else {
574 builder.AppendCStringLiteral(error_suffix);
575 }
576 }
577
578 return builder.Finish().ToHandleChecked();
579}
580
581} // namespace
582
583// static
585 Isolate* isolate, DirectHandle<Object> input) {
586 DisallowJavascriptExecution no_js(isolate);
587
588 if (IsString(*input) || IsNumber(*input) || IsOddball(*input)) {
589 return Object::ToString(isolate, input).ToHandleChecked();
590 } else if (IsJSProxy(*input)) {
591 DirectHandle<Object> currInput = input;
592 do {
593 Tagged<HeapObject> target = Cast<JSProxy>(currInput)->target(isolate);
594 currInput = direct_handle(target, isolate);
595 } while (IsJSProxy(*currInput));
596 return NoSideEffectsToString(isolate, currInput);
597 } else if (IsBigInt(*input)) {
598 return BigInt::NoSideEffectsToString(isolate, Cast<BigInt>(input));
599 } else if (IsJSFunctionOrBoundFunctionOrWrappedFunction(*input)) {
600 // -- F u n c t i o n
601 DirectHandle<String> fun_str;
602 if (IsJSBoundFunction(*input)) {
604 } else if (IsJSWrappedFunction(*input)) {
606 } else {
607 DCHECK(IsJSFunction(*input));
608 fun_str = JSFunction::ToString(Cast<JSFunction>(input));
609 }
610
611 if (fun_str->length() > 128) {
612 IncrementalStringBuilder builder(isolate);
613 builder.AppendString(isolate->factory()->NewSubString(fun_str, 0, 111));
614 builder.AppendCStringLiteral("...<omitted>...");
615 builder.AppendString(isolate->factory()->NewSubString(
616 fun_str, fun_str->length() - 2, fun_str->length()));
617
618 return builder.Finish().ToHandleChecked();
619 }
620 return fun_str;
621 } else if (IsSymbol(*input)) {
622 // -- S y m b o l
623 DirectHandle<Symbol> symbol = Cast<Symbol>(input);
624
625 if (symbol->is_private_name()) {
626 return DirectHandle<String>(Cast<String>(symbol->description()), isolate);
627 }
628
629 IncrementalStringBuilder builder(isolate);
630 builder.AppendCStringLiteral("Symbol(");
631 if (IsString(symbol->description())) {
632 DirectHandle<String> description(Cast<String>(symbol->description()),
633 isolate);
634 if (description->length() > 128) {
635 builder.AppendString(
636 isolate->factory()->NewSubString(description, 0, 56));
637 builder.AppendCStringLiteral("...<omitted>...");
638 builder.AppendString(isolate->factory()->NewSubString(
639 description, description->length() - 56, description->length()));
640 } else {
641 builder.AppendString(description);
642 }
643 }
644 builder.AppendCharacter(')');
645
646 return builder.Finish().ToHandleChecked();
647 } else if (IsJSReceiver(*input)) {
648 // -- J S R e c e i v e r
651 isolate, receiver, isolate->factory()->toString_string());
652
653 if (IsErrorObject(isolate, input) ||
654 *to_string == *isolate->error_to_string()) {
655 // When internally formatting error objects, use a side-effects-free
656 // version of Error.prototype.toString independent of the actually
657 // installed toString method.
658 return NoSideEffectsErrorToString(isolate, receiver);
659 } else if (*to_string == *isolate->object_to_string()) {
661 isolate, receiver, isolate->factory()->constructor_string());
662 if (IsJSFunctionOrBoundFunctionOrWrappedFunction(*ctor)) {
663 DirectHandle<String> ctor_name;
664 if (IsJSBoundFunction(*ctor)) {
665 ctor_name =
667 .ToHandleChecked();
668 } else if (IsJSFunction(*ctor)) {
669 ctor_name = JSFunction::GetName(isolate, Cast<JSFunction>(ctor));
670 }
671
672 if (ctor_name->length() != 0) {
673 IncrementalStringBuilder builder(isolate);
674 builder.AppendCStringLiteral("#<");
675 builder.AppendString(ctor_name);
676 builder.AppendCharacter('>');
677
678 return builder.Finish().ToHandleChecked();
679 }
680 }
681 }
682 }
683 return {};
684}
685
686// static
688 DirectHandle<Object> input) {
689 DisallowJavascriptExecution no_js(isolate);
690
691 // Try to convert input to a meaningful string.
692 MaybeDirectHandle<String> maybe_string =
693 NoSideEffectsToMaybeString(isolate, input);
694 DirectHandle<String> string_handle;
695 if (maybe_string.ToHandle(&string_handle)) {
696 return string_handle;
697 }
698
699 // At this point, input is either none of the above or a JSReceiver.
700
702 if (IsJSReceiver(*input)) {
703 receiver = Cast<JSReceiver>(input);
704 } else {
705 // This is the only case where Object::ToObject throws.
706 DCHECK(!IsSmi(*input));
707 int constructor_function_index =
708 Cast<HeapObject>(input)->map()->GetConstructorFunctionIndex();
709 if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
710 return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
711 }
712
713 receiver = Object::ToObjectImpl(isolate, input).ToHandleChecked();
714 }
715
716 DirectHandle<String> builtin_tag =
717 direct_handle(receiver->class_name(), isolate);
719 isolate, receiver, isolate->factory()->to_string_tag_symbol());
721 IsString(*tag_obj) ? Cast<String>(tag_obj) : builtin_tag;
722
723 IncrementalStringBuilder builder(isolate);
724 builder.AppendCStringLiteral("[object ");
725 builder.AppendString(tag);
726 builder.AppendCharacter(']');
727
728 return builder.Finish().ToHandleChecked();
729}
730
731// static
733 DirectHandle<Object> input) {
734 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input));
735 if (IsSmi(*input)) {
736 int value = std::max(Smi::ToInt(*input), 0);
737 return handle(Smi::FromInt(value), isolate);
738 }
739 double len = DoubleToInteger(Cast<HeapNumber>(*input)->value());
740 if (len <= 0.0) {
741 return handle(Smi::zero(), isolate);
742 } else if (len >= kMaxSafeInteger) {
743 len = kMaxSafeInteger;
744 }
745 return isolate->factory()->NewNumber(len);
746}
747
748// static
749template <template <typename> typename HandleType>
750 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
751typename HandleType<Number>::MaybeType Object::ConvertToIndex(
752 Isolate* isolate, HandleType<Object> input, MessageTemplate error_index) {
753 if (IsUndefined(*input, isolate))
754 return HandleType<Number>(Smi::zero(), isolate);
755 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(isolate, input));
756 if (IsSmi(*input) && Smi::ToInt(*input) >= 0) return Cast<Smi>(input);
757 double len = DoubleToInteger(Object::NumberValue(Cast<Number>(*input)));
758 HandleType<Number> js_len = isolate->factory()->NewNumber(len);
759 if (len < 0.0 || len > kMaxSafeInteger) {
760 THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len));
761 }
762 return js_len;
763}
764
765template V8_EXPORT_PRIVATE MaybeDirectHandle<Number> Object::ConvertToIndex(
766 Isolate* isolate, DirectHandle<Object> input, MessageTemplate error_index);
767template V8_EXPORT_PRIVATE MaybeIndirectHandle<Number> Object::ConvertToIndex(
768 Isolate* isolate, IndirectHandle<Object> input,
769 MessageTemplate error_index);
770
771template <typename IsolateT>
772// static
773bool Object::BooleanValue(Tagged<Object> obj, IsolateT* isolate) {
774 if (IsSmi(obj)) return Smi::ToInt(obj) != 0;
775 DCHECK(IsHeapObject(obj));
776 if (IsBoolean(obj)) return IsTrue(obj, isolate);
777 if (IsNullOrUndefined(obj, isolate)) return false;
778#ifdef V8_ENABLE_WEBASSEMBLY
779 if (IsWasmNull(obj)) return false;
780#endif
781 if (IsUndetectable(obj)) return false; // Undetectable object is false.
782 if (IsString(obj)) return Cast<String>(obj)->length() != 0;
783 if (IsHeapNumber(obj)) return DoubleToBoolean(Cast<HeapNumber>(obj)->value());
784 if (IsBigInt(obj)) return Cast<BigInt>(obj)->ToBoolean();
785 return true;
786}
789
790// static
792 if (IsBoolean(obj)) return obj;
793 return isolate->heap()->ToBoolean(Object::BooleanValue(obj, isolate));
794}
795
796namespace {
797
798// TODO(bmeurer): Maybe we should introduce a marker interface Number,
799// where we put all these methods at some point?
800ComparisonResult StrictNumberCompare(double x, double y) {
801 if (std::isnan(x) || std::isnan(y)) {
803 } else if (x < y) {
805 } else if (x > y) {
807 } else {
809 }
810}
811
812// See Number case of ES6#sec-strict-equality-comparison
813// Returns false if x or y is NaN, treats -0.0 as equal to 0.0.
814bool StrictNumberEquals(double x, double y) {
815 // Must check explicitly for NaN's on Windows, but -0 works fine.
816 if (std::isnan(x) || std::isnan(y)) return false;
817 return x == y;
818}
819
820bool StrictNumberEquals(const Tagged<Number> x, const Tagged<Number> y) {
821 return StrictNumberEquals(Object::NumberValue(x), Object::NumberValue(y));
822}
823
824bool StrictNumberEquals(DirectHandle<Number> x, DirectHandle<Number> y) {
825 return StrictNumberEquals(*x, *y);
826}
827
831 }
834 }
835 return result;
836}
837
838} // anonymous namespace
839
840// static
844 // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
845 if (!Object::ToPrimitive(isolate, x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
846 !Object::ToPrimitive(isolate, y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
848 }
849 if (IsString(*x) && IsString(*y)) {
850 // ES6 section 7.2.11 Abstract Relational Comparison step 5.
851 return Just(String::Compare(isolate, Cast<String>(x), Cast<String>(y)));
852 }
853 if (IsBigInt(*x) && IsString(*y)) {
855 }
856 if (IsString(*x) && IsBigInt(*y)) {
857 Maybe<ComparisonResult> maybe_result =
860 if (maybe_result.To(&result)) {
861 return Just(Reverse(result));
862 } else {
864 }
865 }
866 // ES6 section 7.2.11 Abstract Relational Comparison step 6.
867 if (!Object::ToNumeric(isolate, x).ToHandle(&x) ||
868 !Object::ToNumeric(isolate, y).ToHandle(&y)) {
870 }
871
872 bool x_is_number = IsNumber(*x);
873 bool y_is_number = IsNumber(*y);
874 if (x_is_number && y_is_number) {
875 return Just(
876 StrictNumberCompare(Object::NumberValue(*x), Object::NumberValue(*y)));
877 } else if (!x_is_number && !y_is_number) {
879 } else if (x_is_number) {
880 return Just(Reverse(BigInt::CompareToNumber(Cast<BigInt>(y), x)));
881 } else {
883 }
884}
885
888 // This is the generic version of Abstract Equality Comparison. Must be in
889 // sync with CodeStubAssembler::Equal.
890 while (true) {
891 if (IsNumber(*x)) {
892 if (IsNumber(*y)) {
893 return Just(StrictNumberEquals(Cast<Number>(*x), Cast<Number>(*y)));
894 } else if (IsBoolean(*y)) {
895 return Just(StrictNumberEquals(Cast<Number>(*x),
896 Cast<Oddball>(y)->to_number()));
897 } else if (IsString(*y)) {
898 return Just(StrictNumberEquals(
900 } else if (IsBigInt(*y)) {
902 } else if (IsJSReceiver(*y)) {
904 .ToHandle(&y)) {
905 return Nothing<bool>();
906 }
907 } else {
908 return Just(false);
909 }
910 } else if (IsString(*x)) {
911 if (IsString(*y)) {
912 return Just(String::Equals(isolate, Cast<String>(x), Cast<String>(y)));
913 } else if (IsNumber(*y)) {
914 x = String::ToNumber(isolate, Cast<String>(x));
915 return Just(StrictNumberEquals(Cast<Number>(*x), Cast<Number>(*y)));
916 } else if (IsBoolean(*y)) {
917 x = String::ToNumber(isolate, Cast<String>(x));
918 return Just(StrictNumberEquals(Cast<Number>(*x),
919 Cast<Oddball>(y)->to_number()));
920 } else if (IsBigInt(*y)) {
922 } else if (IsJSReceiver(*y)) {
924 .ToHandle(&y)) {
925 return Nothing<bool>();
926 }
927 } else {
928 return Just(false);
929 }
930 } else if (IsBoolean(*x)) {
931 if (IsOddball(*y)) {
932 return Just(x.is_identical_to(y));
933 } else if (IsNumber(*y)) {
934 return Just(StrictNumberEquals(Cast<Oddball>(x)->to_number(),
935 Cast<Number>(*y)));
936 } else if (IsString(*y)) {
937 y = String::ToNumber(isolate, Cast<String>(y));
938 return Just(StrictNumberEquals(Cast<Oddball>(x)->to_number(),
939 Cast<Number>(*y)));
940 } else if (IsBigInt(*y)) {
941 x = Oddball::ToNumber(isolate, Cast<Oddball>(x));
943 } else if (IsJSReceiver(*y)) {
945 .ToHandle(&y)) {
946 return Nothing<bool>();
947 }
948 x = Oddball::ToNumber(isolate, Cast<Oddball>(x));
949 } else {
950 return Just(false);
951 }
952 } else if (IsSymbol(*x)) {
953 if (IsSymbol(*y)) {
954 return Just(x.is_identical_to(y));
955 } else if (IsJSReceiver(*y)) {
957 .ToHandle(&y)) {
958 return Nothing<bool>();
959 }
960 } else {
961 return Just(false);
962 }
963 } else if (IsBigInt(*x)) {
964 if (IsBigInt(*y)) {
966 }
967 return Equals(isolate, y, x);
968 } else if (IsJSReceiver(*x)) {
969 if (IsJSReceiver(*y)) {
970 return Just(x.is_identical_to(y));
971 } else if (IsUndetectable(*y)) {
972 return Just(IsUndetectable(*x));
973 } else if (IsBoolean(*y)) {
974 y = Oddball::ToNumber(isolate, Cast<Oddball>(y));
975 } else if (!JSReceiver::ToPrimitive(isolate, Cast<JSReceiver>(x))
976 .ToHandle(&x)) {
977 return Nothing<bool>();
978 }
979 } else {
980 return Just(IsUndetectable(*x) && IsUndetectable(*y));
981 }
982 }
983}
984
985// static
987 if (IsNumber(obj)) {
988 if (!IsNumber(that)) return false;
989 return StrictNumberEquals(Cast<Number>(obj), Cast<Number>(that));
990 } else if (IsString(obj)) {
991 if (!IsString(that)) return false;
992 return Cast<String>(obj)->Equals(Cast<String>(that));
993 } else if (IsBigInt(obj)) {
994 if (!IsBigInt(that)) return false;
996 }
997 return obj == that;
998}
999
1000// static
1002 if (IsNumber(*object)) return isolate->factory()->number_string();
1003 if (IsOddball(*object))
1004 return handle(Cast<Oddball>(*object)->type_of(), isolate);
1005 if (IsUndetectable(*object)) {
1006 return isolate->factory()->undefined_string();
1007 }
1008 if (IsString(*object)) return isolate->factory()->string_string();
1009 if (IsSymbol(*object)) return isolate->factory()->symbol_string();
1010 if (IsBigInt(*object)) return isolate->factory()->bigint_string();
1011 if (IsCallable(*object)) return isolate->factory()->function_string();
1012 return isolate->factory()->object_string();
1013}
1014
1015// static
1017 Handle<Object> rhs) {
1018 if (IsNumber(*lhs) && IsNumber(*rhs)) {
1019 return isolate->factory()->NewNumber(
1022 } else if (IsString(*lhs) && IsString(*rhs)) {
1023 return isolate->factory()->NewConsString(Cast<String>(lhs),
1024 Cast<String>(rhs));
1025 }
1026 ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(isolate, lhs));
1027 ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(isolate, rhs));
1028 if (IsString(*lhs) || IsString(*rhs)) {
1029 ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs));
1030 ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs));
1031 return isolate->factory()->NewConsString(Cast<String>(lhs),
1032 Cast<String>(rhs));
1033 }
1034 DirectHandle<Number> lhs_number;
1035 DirectHandle<Number> rhs_number;
1036 ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs_number,
1037 Object::ToNumber(isolate, rhs));
1038 ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs_number,
1039 Object::ToNumber(isolate, lhs));
1040 return isolate->factory()->NewNumber(Object::NumberValue(*lhs_number) +
1041 Object::NumberValue(*rhs_number));
1042}
1043
1044// static
1046 DirectHandle<JSAny> callable,
1047 DirectHandle<JSAny> object) {
1048 // The {callable} must have a [[Call]] internal method.
1049 if (!IsCallable(*callable)) return isolate->factory()->false_value();
1050
1051 // Check if {callable} is a bound function, and if so retrieve its
1052 // [[BoundTargetFunction]] and use that instead of {callable}.
1053 if (IsJSBoundFunction(*callable)) {
1054 // Since there is a mutual recursion here, we might run out of stack
1055 // space for long chains of bound functions.
1056 STACK_CHECK(isolate, MaybeHandle<Object>());
1057 DirectHandle<JSCallable> bound_callable(
1058 Cast<JSBoundFunction>(callable)->bound_target_function(), isolate);
1059 return Object::InstanceOf(isolate, object, bound_callable);
1060 }
1061
1062 // If {object} is not a receiver, return false.
1063 if (!IsJSReceiver(*object)) return isolate->factory()->false_value();
1064
1065 // Get the "prototype" of {callable}; raise an error if it's not a receiver.
1068 isolate, prototype,
1069 Object::GetProperty(isolate, callable,
1070 isolate->factory()->prototype_string()));
1071 if (!IsJSReceiver(*prototype)) {
1073 isolate,
1074 NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype));
1075 }
1076
1077 // Return whether or not {prototype} is in the prototype chain of {object}.
1079 isolate, Cast<JSReceiver>(object), prototype);
1080 if (result.IsNothing()) return MaybeHandle<Object>();
1081 return isolate->factory()->ToBoolean(result.FromJust());
1082}
1083
1084// static
1086 DirectHandle<JSAny> object,
1087 DirectHandle<JSAny> callable) {
1088 // The {callable} must be a receiver.
1089 if (!IsJSReceiver(*callable)) {
1090 THROW_NEW_ERROR(isolate,
1091 NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck));
1092 }
1093
1094 // Lookup the @@hasInstance method on {callable}.
1095 DirectHandle<Object> inst_of_handler;
1097 isolate, inst_of_handler,
1098 Object::GetMethod(isolate, Cast<JSReceiver>(callable),
1099 isolate->factory()->has_instance_symbol()));
1100 if (!IsUndefined(*inst_of_handler, isolate)) {
1101 // Call the {inst_of_handler} on the {callable}.
1103 DirectHandle<Object> args[] = {object};
1105 Execution::Call(isolate, inst_of_handler,
1106 callable, base::VectorOf(args)));
1107 return isolate->factory()->ToBoolean(
1108 Object::BooleanValue(*result, isolate));
1109 }
1110
1111 // The {callable} must have a [[Call]] internal method.
1112 if (!IsCallable(*callable)) {
1114 isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck));
1115 }
1116
1117 // Fall back to OrdinaryHasInstance with {callable} and {object}.
1120 isolate, result, Object::OrdinaryHasInstance(isolate, callable, object));
1121 return result;
1122}
1123
1124// static
1127 DirectHandle<Name> name) {
1128 Handle<Object> func;
1129 ASSIGN_RETURN_ON_EXCEPTION(isolate, func,
1130 JSReceiver::GetProperty(isolate, receiver, name));
1131 if (IsNullOrUndefined(*func, isolate)) {
1132 return isolate->factory()->undefined_value();
1133 }
1134 if (!IsCallable(*func)) {
1135 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kPropertyNotFunction,
1136 func, name, receiver));
1137 }
1138 return func;
1139}
1140
1141namespace {
1142
1143MaybeDirectHandle<FixedArray> CreateListFromArrayLikeFastPath(
1144 Isolate* isolate, DirectHandle<Object> object, ElementTypes element_types) {
1145 if (element_types == ElementTypes::kAll) {
1146 if (IsJSArray(*object)) {
1147 DirectHandle<JSArray> array = Cast<JSArray>(object);
1148 uint32_t length;
1149 if (!array->HasArrayPrototype(isolate) ||
1150 !Object::ToUint32(array->length(), &length) ||
1151 !array->HasFastElements() ||
1152 !JSObject::PrototypeHasNoElements(isolate, *array)) {
1154 }
1155 return array->GetElementsAccessor()->CreateListFromArrayLike(
1156 isolate, array, length);
1157 } else if (IsJSTypedArray(*object)) {
1158 DirectHandle<JSTypedArray> array = Cast<JSTypedArray>(object);
1159 size_t length = array->GetLength();
1160 if (array->IsDetachedOrOutOfBounds() ||
1161 length > static_cast<size_t>(FixedArray::kMaxLength)) {
1162 return MaybeDirectHandle<FixedArray>();
1163 }
1164 static_assert(FixedArray::kMaxLength <=
1165 std::numeric_limits<uint32_t>::max());
1166 return array->GetElementsAccessor()->CreateListFromArrayLike(
1167 isolate, array, static_cast<uint32_t>(length));
1168 }
1169 }
1170 return MaybeDirectHandle<FixedArray>();
1171}
1172
1173} // namespace
1174
1175// static
1177 Isolate* isolate, DirectHandle<Object> object, ElementTypes element_types) {
1178 // Fast-path for JSArray and JSTypedArray.
1179 MaybeDirectHandle<FixedArray> fast_result =
1180 CreateListFromArrayLikeFastPath(isolate, object, element_types);
1181 if (!fast_result.is_null()) return fast_result;
1182 // 1. ReturnIfAbrupt(object).
1183 // 2. (default elementTypes -- not applicable.)
1184 // 3. If Type(obj) is not Object, throw a TypeError exception.
1185 if (!IsJSReceiver(*object)) {
1186 THROW_NEW_ERROR(isolate,
1187 NewTypeError(MessageTemplate::kCalledOnNonObject,
1188 isolate->factory()->NewStringFromAsciiChecked(
1189 "CreateListFromArrayLike")));
1190 }
1191
1192 // 4. Let len be ? ToLength(? Get(obj, "length")).
1194 DirectHandle<Object> raw_length_number;
1195 ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
1197 uint32_t len;
1198 if (!Object::ToUint32(*raw_length_number, &len) ||
1199 len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
1200 THROW_NEW_ERROR(isolate,
1201 NewRangeError(MessageTemplate::kInvalidArrayLength));
1202 }
1203 // 5. Let list be an empty List.
1204 DirectHandle<FixedArray> list = isolate->factory()->NewFixedArray(len);
1205 // 6. Let index be 0.
1206 // 7. Repeat while index < len:
1207 for (uint32_t index = 0; index < len; ++index) {
1208 // 7a. Let indexName be ToString(index).
1209 // 7b. Let next be ? Get(obj, indexName).
1212 isolate, next, JSReceiver::GetElement(isolate, receiver, index));
1213 switch (element_types) {
1214 case ElementTypes::kAll:
1215 // Nothing to do.
1216 break;
1218 // 7c. If Type(next) is not an element of elementTypes, throw a
1219 // TypeError exception.
1220 if (!IsName(*next)) {
1222 isolate, NewTypeError(MessageTemplate::kNotPropertyName, next));
1223 }
1224 // 7d. Append next as the last element of list.
1225 // Internalize on the fly so we can use pointer identity later.
1226 next = isolate->factory()->InternalizeName(Cast<Name>(next));
1227 break;
1228 }
1229 }
1230 list->set(index, *next);
1231 // 7e. Set index to index + 1. (See loop header.)
1232 }
1233 // 8. Return list.
1234 return list;
1235}
1236
1237// static
1239 Isolate* isolate, DirectHandle<JSReceiver> object) {
1241 DirectHandle<Name> key = isolate->factory()->length_string();
1242 ASSIGN_RETURN_ON_EXCEPTION(isolate, val,
1243 JSReceiver::GetProperty(isolate, object, key));
1244 return Object::ToLength(isolate, val);
1245}
1246
1247// static
1249 bool is_global_reference) {
1250 for (;; it->Next()) {
1251 switch (it->state()) {
1253 UNREACHABLE();
1255 bool was_found;
1256 DirectHandle<JSAny> receiver = it->GetReceiver();
1257 // In case of global IC, the receiver is the global object. Replace by
1258 // the global proxy.
1259 if (IsJSGlobalObject(*receiver)) {
1261 Cast<JSGlobalObject>(*receiver)->global_proxy(), it->isolate());
1262 }
1263 if (is_global_reference) {
1265 it->isolate(), it->GetHolder<JSProxy>(), it->GetName());
1266 if (maybe.IsNothing()) return {};
1267 if (!maybe.FromJust()) {
1268 it->NotFound();
1269 return it->isolate()->factory()->undefined_value();
1270 }
1271 }
1273 JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(),
1274 it->GetName(), receiver, &was_found);
1275 if (!was_found && !is_global_reference) it->NotFound();
1276 return result;
1277 }
1279 continue; // Continue to the prototype, if present.
1281 bool done;
1284 it->isolate(), result,
1286 if (done) return result;
1287 continue;
1288 }
1290 if (it->HasAccess()) continue;
1293 return GetPropertyWithAccessor(it);
1295 return it->isolate()->factory()->undefined_value();
1297 return it->GetDataValue();
1299 if (it->IsPrivateName()) {
1300 auto private_symbol = Cast<Symbol>(it->name());
1301 DirectHandle<String> name_string(
1302 Cast<String>(private_symbol->description()), it->isolate());
1303 if (private_symbol->is_private_brand()) {
1304 DirectHandle<String> class_name =
1305 name_string->length() == 0
1306 ? it->isolate()->factory()->anonymous_string()
1307 : name_string;
1309 it->isolate(),
1310 NewTypeError(MessageTemplate::kInvalidPrivateBrandInstance,
1311 class_name));
1312 }
1314 it->isolate(),
1315 NewTypeError(MessageTemplate::kInvalidPrivateMemberRead,
1316 name_string));
1317 }
1318
1319 return it->isolate()->factory()->undefined_value();
1320 }
1321 UNREACHABLE();
1322 }
1323}
1324
1325// static
1328 DirectHandle<Name> name,
1330 bool* was_found) {
1331 *was_found = true;
1332
1333 DCHECK(!name->IsPrivate());
1334 STACK_CHECK(isolate, kNullMaybeHandle);
1335 DirectHandle<Name> trap_name = isolate->factory()->get_string();
1336 // 1. Assert: IsPropertyKey(P) is true.
1337 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
1338 DirectHandle<UnionOf<JSReceiver, Null>> handler(proxy->handler(), isolate);
1339 // 3. If handler is null, throw a TypeError exception.
1340 // 4. Assert: Type(handler) is Object.
1341 if (proxy->IsRevoked()) {
1342 THROW_NEW_ERROR(isolate,
1343 NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
1344 }
1345 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
1346 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
1347 // 6. Let trap be ? GetMethod(handler, "get").
1350 isolate, trap,
1351 Object::GetMethod(isolate, Cast<JSReceiver>(handler), trap_name));
1352 // 7. If trap is undefined, then
1353 if (IsUndefined(*trap, isolate)) {
1354 // 7.a Return target.[[Get]](P, Receiver).
1355 PropertyKey key(isolate, name);
1356 LookupIterator it(isolate, receiver, key, target);
1358 *was_found = it.IsFound();
1359 return result;
1360 }
1361 // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»).
1362 Handle<Object> trap_result;
1365 isolate, trap_result,
1366 Execution::Call(isolate, trap, handler, base::VectorOf(args)));
1367
1369 JSProxy::CheckGetSetTrapResult(isolate, name, target, trap_result, kGet);
1370 if (result.is_null()) {
1371 return result;
1372 }
1373
1374 // 11. Return trap_result
1375 return Cast<JSAny>(trap_result);
1376}
1377
1378// static
1381 DirectHandle<Object> trap_result, AccessKind access_kind) {
1382 // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
1383 PropertyDescriptor target_desc;
1384 Maybe<bool> target_found =
1385 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
1386 MAYBE_RETURN_NULL(target_found);
1387 // 10. If targetDesc is not undefined, then
1388 if (target_found.FromJust()) {
1389 // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is
1390 // false and targetDesc.[[Writable]] is false, then
1391 // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
1392 // throw a TypeError exception.
1393 bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) &&
1394 !target_desc.configurable() &&
1395 !target_desc.writable() &&
1396 !Object::SameValue(*trap_result, *target_desc.value());
1397 if (inconsistent) {
1398 if (access_kind == kGet) {
1400 isolate, NewTypeError(MessageTemplate::kProxyGetNonConfigurableData,
1401 name, target_desc.value(), trap_result));
1402 } else {
1403 isolate->Throw(*isolate->factory()->NewTypeError(
1404 MessageTemplate::kProxySetFrozenData, name));
1405 return {};
1406 }
1407 }
1408 // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]]
1409 // is false and targetDesc.[[Get]] is undefined, then
1410 // 10.b.i. If trapResult is not undefined, throw a TypeError exception.
1411 if (access_kind == kGet) {
1412 inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
1413 !target_desc.configurable() &&
1414 IsUndefined(*target_desc.get(), isolate) &&
1415 !IsUndefined(*trap_result, isolate);
1416 } else {
1417 inconsistent = PropertyDescriptor::IsAccessorDescriptor(&target_desc) &&
1418 !target_desc.configurable() &&
1419 IsUndefined(*target_desc.set(), isolate);
1420 }
1421 if (inconsistent) {
1422 if (access_kind == kGet) {
1424 isolate,
1425 NewTypeError(MessageTemplate::kProxyGetNonConfigurableAccessor,
1426 name, trap_result));
1427 } else {
1428 isolate->Throw(*isolate->factory()->NewTypeError(
1429 MessageTemplate::kProxySetFrozenAccessor, name));
1430 return {};
1431 }
1432 }
1433 }
1434 return isolate->factory()->undefined_value();
1435}
1436
1437// static
1438bool Object::ToInt32(Tagged<Object> obj, int32_t* value) {
1439 if (IsSmi(obj)) {
1440 *value = Smi::ToInt(obj);
1441 return true;
1442 }
1443 if (IsHeapNumber(obj)) {
1444 double num = Cast<HeapNumber>(obj)->value();
1445 // Check range before conversion to avoid undefined behavior.
1446 if (num >= kMinInt && num <= kMaxInt && FastI2D(FastD2I(num)) == num) {
1447 *value = FastD2I(num);
1448 return true;
1449 }
1450 }
1451 return false;
1452}
1453
1454// ES6 9.5.1
1455// static
1457 DirectHandle<JSProxy> proxy) {
1458 Isolate* isolate = proxy->GetIsolate();
1459 DirectHandle<String> trap_name = isolate->factory()->getPrototypeOf_string();
1460
1461 STACK_CHECK(isolate, {});
1462
1463 // 1. Let handler be the value of the [[ProxyHandler]] internal slot.
1464 // 2. If handler is null, throw a TypeError exception.
1465 // 3. Assert: Type(handler) is Object.
1466 // 4. Let target be the value of the [[ProxyTarget]] internal slot.
1467 if (proxy->IsRevoked()) {
1468 THROW_NEW_ERROR(isolate,
1469 NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
1470 }
1471 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
1472 DirectHandle<JSReceiver> handler(Cast<JSReceiver>(proxy->handler()), isolate);
1473
1474 // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
1477 Object::GetMethod(isolate, handler, trap_name));
1478 // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
1479 if (IsUndefined(*trap, isolate)) {
1480 return JSReceiver::GetPrototype(isolate, target);
1481 }
1482 // 7. Let handlerProto be ? Call(trap, handler, «target»).
1483 DirectHandle<Object> args[] = {target};
1484 DirectHandle<Object> handler_proto_result;
1486 isolate, handler_proto_result,
1487 Execution::Call(isolate, trap, handler, base::VectorOf(args)));
1488 // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
1489 DirectHandle<JSPrototype> handler_proto;
1490 if (!TryCast(handler_proto_result, &handler_proto)) {
1491 THROW_NEW_ERROR(isolate,
1492 NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid));
1493 }
1494 // 9. Let extensibleTarget be ? IsExtensible(target).
1497 // 10. If extensibleTarget is true, return handlerProto.
1498 if (is_extensible.FromJust()) return handler_proto;
1499 // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
1500 DirectHandle<JSPrototype> target_proto;
1501 ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
1502 JSReceiver::GetPrototype(isolate, target));
1503 // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
1504 if (!Object::SameValue(*handler_proto, *target_proto)) {
1506 isolate,
1507 NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible));
1508 }
1509 // 13. Return handlerProto.
1510 return handler_proto;
1511}
1512
1514 Isolate* isolate = it->isolate();
1515 DirectHandle<Object> structure = it->GetAccessors();
1516 DirectHandle<JSAny> receiver = it->GetReceiver();
1517 // In case of global IC, the receiver is the global object. Replace by the
1518 // global proxy.
1519 if (IsJSGlobalObject(*receiver)) {
1520 receiver =
1521 direct_handle(Cast<JSGlobalObject>(*receiver)->global_proxy(), isolate);
1522 }
1523
1524 // We should never get here to initialize a const with the hole value since a
1525 // const declaration would conflict with the getter.
1526 DCHECK(!IsForeign(*structure));
1527
1528 // API style callbacks.
1529 DirectHandle<JSObject> holder = it->GetHolder<JSObject>();
1530 if (IsAccessorInfo(*structure)) {
1531 DirectHandle<Name> name = it->GetName();
1532 auto info = Cast<AccessorInfo>(structure);
1533
1534 if (!info->has_getter(isolate)) {
1535 return isolate->factory()->undefined_value();
1536 }
1537
1538 if (info->is_sloppy() && !IsJSReceiver(*receiver)) {
1541 }
1542
1543 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
1544 Just(kDontThrow));
1545 DirectHandle<JSAny> result = args.CallAccessorGetter(info, name);
1547 Handle<JSAny> reboxed_result(*result, isolate);
1548 if (info->replace_on_access() && IsJSReceiver(*receiver)) {
1549 RETURN_ON_EXCEPTION(isolate,
1551 isolate, receiver, holder, name, result));
1552 }
1553 return reboxed_result;
1554 }
1555
1556 auto accessor_pair = Cast<AccessorPair>(structure);
1557 // AccessorPair with 'cached' private property.
1558 if (it->TryLookupCachedProperty(accessor_pair)) {
1559 return Cast<JSAny>(Object::GetProperty(it));
1560 }
1561
1562 // Regular accessor.
1563 DirectHandle<Object> getter(accessor_pair->getter(), isolate);
1564 if (IsFunctionTemplateInfo(*getter)) {
1565 SaveAndSwitchContext save(isolate, holder->GetCreationContext().value());
1567 isolate, false, Cast<FunctionTemplateInfo>(getter), receiver, {},
1568 isolate->factory()->undefined_value()));
1569 } else if (IsCallable(*getter)) {
1570 // TODO(rossberg): nicer would be to cast to some JSCallable here...
1573 }
1574 // Getter is not a function.
1575 return isolate->factory()->undefined_value();
1576}
1577
1580 Maybe<ShouldThrow> maybe_should_throw) {
1581 Isolate* isolate = it->isolate();
1582 DirectHandle<Object> structure = it->GetAccessors();
1583 DirectHandle<JSAny> receiver = it->GetReceiver();
1584 // In case of global IC, the receiver is the global object. Replace by the
1585 // global proxy.
1586 if (IsJSGlobalObject(*receiver)) {
1587 receiver =
1588 direct_handle(Cast<JSGlobalObject>(*receiver)->global_proxy(), isolate);
1589 }
1590
1591 // We should never get here to initialize a const with the hole value since a
1592 // const declaration would conflict with the setter.
1593 DCHECK(!IsForeign(*structure));
1594
1595 // API style callbacks.
1596 DirectHandle<JSObject> holder = it->GetHolder<JSObject>();
1597 if (IsAccessorInfo(*structure)) {
1598 DirectHandle<Name> name = it->GetName();
1599 auto info = Cast<AccessorInfo>(structure);
1600
1601 if (!info->has_setter(isolate)) {
1602 // TODO(verwaest): We should not get here anymore once all AccessorInfos
1603 // are marked as special_data_property. They cannot both be writable and
1604 // not have a setter.
1605 return Just(true);
1606 }
1607
1608 if (info->is_sloppy() && !IsJSReceiver(*receiver)) {
1610 isolate, receiver, Object::ConvertReceiver(isolate, receiver),
1611 Nothing<bool>());
1612 }
1613
1614 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
1615 maybe_should_throw);
1616 bool result = args.CallAccessorSetter(info, name, value);
1618 // Ensure the setter callback respects the "should throw" value - it's
1619 // allowed to fail without throwing only in case of kDontThrow.
1621 GetShouldThrow(isolate, maybe_should_throw) == kDontThrow);
1622 return Just(result);
1623 }
1624
1625 // Regular accessor.
1626 DirectHandle<Object> setter(Cast<AccessorPair>(*structure)->setter(),
1627 isolate);
1628 if (IsFunctionTemplateInfo(*setter)) {
1629 SaveAndSwitchContext save(isolate, holder->GetCreationContext().value());
1630 DirectHandle<Object> args[] = {value};
1632 isolate,
1634 isolate, false, Cast<FunctionTemplateInfo>(setter), receiver,
1635 base::VectorOf(args), isolate->factory()->undefined_value()),
1636 Nothing<bool>());
1637 return Just(true);
1638 } else if (IsCallable(*setter)) {
1639 // TODO(rossberg): nicer would be to cast to some JSCallable here...
1641 value, maybe_should_throw);
1642 }
1643
1644 RETURN_FAILURE(isolate, GetShouldThrow(isolate, maybe_should_throw),
1645 NewTypeError(MessageTemplate::kNoSetterInCallback,
1646 it->GetName(), it->GetHolder<JSObject>()));
1647}
1648
1651 Isolate* isolate = getter->GetIsolate();
1652
1653 // Platforms with simulators like arm/arm64 expose a funny issue. If the
1654 // simulator has a separate JS stack pointer from the C++ stack pointer, it
1655 // can miss C++ stack overflows in the stack guard at the start of JavaScript
1656 // functions. It would be very expensive to check the C++ stack pointer at
1657 // that location. The best solution seems to be to break the impasse by
1658 // adding checks at possible recursion points. What's more, we don't put
1659 // this stack check behind the USE_SIMULATOR define in order to keep
1660 // behavior the same between hardware and simulators.
1661 StackLimitCheck check(isolate);
1662 if (check.JsHasOverflowed()) {
1663 isolate->StackOverflow();
1664 return kNullMaybeHandle;
1665 }
1666
1667 return Cast<JSAny>(Execution::Call(isolate, getter, receiver, {}));
1668}
1669
1681
1682// static
1684 Isolate* isolate) {
1686 if (IsSmi(obj)) {
1687 Tagged<Context> native_context = isolate->context()->native_context();
1688 return native_context->number_function()->initial_map();
1689 }
1690
1691 const Tagged<HeapObject> heap_object = Cast<HeapObject>(obj);
1692 return heap_object->map()->GetPrototypeChainRootMap(isolate);
1693}
1694
1695// static
1699 if (IsSmi(hash)) return Cast<Smi>(hash);
1700
1701 DCHECK(IsJSReceiver(obj));
1702 return Cast<JSReceiver>(obj)->GetOrCreateIdentityHash(isolate);
1703}
1704
1705// static
1707 if (other == obj) return true;
1708
1709 if (IsNumber(obj) && IsNumber(other)) {
1712 }
1713 if (IsString(obj) && IsString(other)) {
1714 return Cast<String>(obj)->Equals(Cast<String>(other));
1715 }
1716 if (IsBigInt(obj) && IsBigInt(other)) {
1717 return BigInt::EqualToBigInt(Cast<BigInt>(obj), Cast<BigInt>(other));
1718 }
1719 return false;
1720}
1721
1722// static
1724 if (other == obj) return true;
1725
1726 if (IsNumber(obj) && IsNumber(other)) {
1727 double this_value = Object::NumberValue(Cast<Number>(obj));
1728 double other_value = Object::NumberValue(Cast<Number>(other));
1729 // +0 == -0 is true
1730 return this_value == other_value ||
1731 (std::isnan(this_value) && std::isnan(other_value));
1732 }
1733 if (IsString(obj) && IsString(other)) {
1734 return Cast<String>(obj)->Equals(Cast<String>(other));
1735 }
1736 if (IsBigInt(obj) && IsBigInt(other)) {
1737 return BigInt::EqualToBigInt(Cast<BigInt>(obj), Cast<BigInt>(other));
1738 }
1739 return false;
1740}
1741
1743 Isolate* isolate, DirectHandle<JSAny> original_array) {
1744 DirectHandle<Object> default_species = isolate->array_function();
1745 if (!v8_flags.builtin_subclassing) return default_species;
1746 if (IsJSArray(*original_array) &&
1747 Cast<JSArray>(original_array)->HasArrayPrototype(isolate) &&
1748 Protectors::IsArraySpeciesLookupChainIntact(isolate)) {
1749 return default_species;
1750 }
1751 DirectHandle<Object> constructor = isolate->factory()->undefined_value();
1752 Maybe<bool> is_array = IsArray(original_array);
1753 MAYBE_RETURN_NULL(is_array);
1754 if (is_array.FromJust()) {
1756 isolate, constructor,
1757 Object::GetProperty(isolate, original_array,
1758 isolate->factory()->constructor_string()));
1759 if (IsConstructor(*constructor)) {
1760 DirectHandle<NativeContext> constructor_context;
1762 isolate, constructor_context,
1764 if (*constructor_context != *isolate->native_context() &&
1765 *constructor == constructor_context->array_function()) {
1766 constructor = isolate->factory()->undefined_value();
1767 }
1768 }
1769 if (IsJSReceiver(*constructor)) {
1771 isolate, constructor,
1772 JSReceiver::GetProperty(isolate, Cast<JSReceiver>(constructor),
1773 isolate->factory()->species_symbol()));
1774 if (IsNull(*constructor, isolate)) {
1775 constructor = isolate->factory()->undefined_value();
1776 }
1777 }
1778 }
1779 if (IsUndefined(*constructor, isolate)) {
1780 return default_species;
1781 } else {
1782 if (!IsConstructor(*constructor)) {
1783 THROW_NEW_ERROR(isolate,
1784 NewTypeError(MessageTemplate::kSpeciesNotConstructor));
1785 }
1786 return constructor;
1787 }
1788}
1789
1790// ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
1792 Isolate* isolate, DirectHandle<JSReceiver> recv,
1793 DirectHandle<JSFunction> default_ctor) {
1794 DirectHandle<Object> ctor_obj;
1796 isolate, ctor_obj,
1797 JSObject::GetProperty(isolate, recv,
1798 isolate->factory()->constructor_string()));
1799
1800 if (IsUndefined(*ctor_obj, isolate)) return default_ctor;
1801
1802 if (!IsJSReceiver(*ctor_obj)) {
1803 THROW_NEW_ERROR(isolate,
1804 NewTypeError(MessageTemplate::kConstructorNotReceiver));
1805 }
1806
1808
1809 DirectHandle<Object> species;
1811 isolate, species,
1812 JSObject::GetProperty(isolate, ctor,
1813 isolate->factory()->species_symbol()));
1814
1815 if (IsNullOrUndefined(*species, isolate)) {
1816 return default_ctor;
1817 }
1818
1819 if (IsConstructor(*species)) return species;
1820
1821 THROW_NEW_ERROR(isolate,
1822 NewTypeError(MessageTemplate::kSpeciesNotConstructor));
1823}
1824
1825// static
1828 // Check that this object is an array.
1829 if (!IsJSArray(obj)) return true;
1830 Tagged<JSArray> array = Cast<JSArray>(obj);
1831
1832 // Check that we have the original ArrayPrototype.
1833 Tagged<Object> array_proto = array->map()->prototype();
1834 if (!IsJSObject(array_proto)) return true;
1835 Tagged<NativeContext> native_context = array->GetCreationContext().value();
1836 auto initial_array_prototype = native_context->initial_array_prototype();
1837 if (initial_array_prototype != array_proto) return true;
1838
1839 Isolate* isolate = array->GetIsolate();
1840 // Check that the ArrayPrototype hasn't been modified in a way that would
1841 // affect iteration.
1842 if (!Protectors::IsArrayIteratorLookupChainIntact(isolate)) return true;
1843
1844 // For FastPacked kinds, iteration will have the same effect as simply
1845 // accessing each property in order.
1846 ElementsKind array_kind = array->GetElementsKind();
1847 if (IsFastPackedElementsKind(array_kind)) return false;
1848
1849 // For FastHoley kinds, an element access on a hole would cause a lookup on
1850 // the prototype. This could have different results if the prototype has been
1851 // changed.
1852 if (IsHoleyElementsKind(array_kind) &&
1853 Protectors::IsNoElementsIntact(isolate)) {
1854 return false;
1855 }
1856 return true;
1857}
1858
1859// static
1862 return IsJSReceiver(obj) && Cast<JSReceiver>(obj)->IsCodeLike(isolate);
1863}
1864
1865void ShortPrint(Tagged<Object> obj, FILE* out) {
1866 OFStream os(out);
1867 os << Brief(obj);
1868}
1869
1870void ShortPrint(Tagged<Object> obj, StringStream* accumulator) {
1871 std::ostringstream os;
1872 os << Brief(obj);
1873 accumulator->Add(os.str().c_str());
1874}
1875
1876void ShortPrint(Tagged<Object> obj, std::ostream& os) { os << Brief(obj); }
1877
1878std::ostream& operator<<(std::ostream& os, Tagged<Object> obj) {
1879 ShortPrint(obj, os);
1880 return os;
1881}
1882
1883std::ostream& operator<<(std::ostream& os, Object::Conversion kind) {
1884 switch (kind) {
1886 return os << "ToNumber";
1888 return os << "ToNumeric";
1889 }
1890 UNREACHABLE();
1891}
1892
1893std::ostream& operator<<(std::ostream& os, const Brief& v) {
1894 Tagged<MaybeObject> maybe_object(v.value);
1895 Tagged<Smi> smi;
1896 Tagged<HeapObject> heap_object;
1897 if (maybe_object.ToSmi(&smi)) {
1898 Smi::SmiPrint(smi, os);
1899 } else if (maybe_object.IsCleared()) {
1900 os << "[cleared]";
1901 } else if (maybe_object.GetHeapObjectIfWeak(&heap_object)) {
1902 os << "[weak] ";
1903 heap_object->HeapObjectShortPrint(os);
1904 } else if (maybe_object.GetHeapObjectIfStrong(&heap_object)) {
1905 heap_object->HeapObjectShortPrint(os);
1906 } else {
1907 UNREACHABLE();
1908 }
1909 return os;
1910}
1911
1912// static
1913void Smi::SmiPrint(Tagged<Smi> smi, std::ostream& os) { os << smi.value(); }
1914
1915void Struct::BriefPrintDetails(std::ostream& os) {}
1916
1917void StructLayout::BriefPrintDetails(std::ostream& os) {}
1918
1919void Tuple2::BriefPrintDetails(std::ostream& os) {
1920 os << " " << Brief(value1()) << ", " << Brief(value2());
1921}
1922
1924 os << " " << Brief(accessor(kAcquireLoad)) << ", " << Brief(context());
1925}
1926
1928 os << " " << start() << ", " << end();
1929}
1930
1931void CallableTask::BriefPrintDetails(std::ostream& os) {
1932 os << " callable=" << Brief(callable());
1933}
1934
1936 return Tagged<HeapObject>(this)->SizeFromMap(map);
1937}
1938
1940 int instance_size = map->instance_size();
1941 if (instance_size != kVariableSizeSentinel) return instance_size;
1942 // Only inline the most frequent cases.
1943 InstanceType instance_type = map->instance_type();
1944 if (base::IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE,
1945 LAST_FIXED_ARRAY_TYPE)) {
1946 return UncheckedCast<FixedArray>(*this)->AllocatedSize();
1947 }
1948#define CASE(TypeCamelCase, TYPE_UPPER_CASE) \
1949 if (instance_type == TYPE_UPPER_CASE##_TYPE) { \
1950 return UncheckedCast<TypeCamelCase>(*this)->AllocatedSize(); \
1951 }
1953#undef CASE
1954 if (instance_type == SLOPPY_ARGUMENTS_ELEMENTS_TYPE) {
1955 return UncheckedCast<SloppyArgumentsElements>(*this)->AllocatedSize();
1956 }
1957 if (base::IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) {
1958 if (instance_type == NATIVE_CONTEXT_TYPE) return NativeContext::kSize;
1959 return Context::SizeFor(UncheckedCast<Context>(*this)->length());
1960 }
1961 if (instance_type == SEQ_ONE_BYTE_STRING_TYPE ||
1962 instance_type == INTERNALIZED_ONE_BYTE_STRING_TYPE ||
1963 instance_type == SHARED_SEQ_ONE_BYTE_STRING_TYPE) {
1964 // Strings may get concurrently truncated, hence we have to access its
1965 // length synchronized.
1968 }
1969 if (instance_type == BYTECODE_ARRAY_TYPE) {
1972 }
1973 if (instance_type == FREE_SPACE_TYPE) {
1974 return UncheckedCast<FreeSpace>(*this)->size(kRelaxedLoad);
1975 }
1976 if (instance_type == SEQ_TWO_BYTE_STRING_TYPE ||
1977 instance_type == INTERNALIZED_TWO_BYTE_STRING_TYPE ||
1978 instance_type == SHARED_SEQ_TWO_BYTE_STRING_TYPE) {
1979 // Strings may get concurrently truncated, hence we have to access its
1980 // length synchronized.
1983 }
1984 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
1985 return UncheckedCast<FixedDoubleArray>(*this)->AllocatedSize();
1986 }
1987 if (instance_type == TRUSTED_FIXED_ARRAY_TYPE) {
1988 return UncheckedCast<TrustedFixedArray>(*this)->AllocatedSize();
1989 }
1990 if (instance_type == PROTECTED_FIXED_ARRAY_TYPE) {
1991 return UncheckedCast<ProtectedFixedArray>(*this)->AllocatedSize();
1992 }
1993 if (instance_type == PROTECTED_WEAK_FIXED_ARRAY_TYPE) {
1994 return UncheckedCast<ProtectedWeakFixedArray>(*this)->AllocatedSize();
1995 }
1996 if (instance_type == TRUSTED_WEAK_FIXED_ARRAY_TYPE) {
1997 return UncheckedCast<TrustedWeakFixedArray>(*this)->AllocatedSize();
1998 }
1999 if (instance_type == TRUSTED_BYTE_ARRAY_TYPE) {
2000 return UncheckedCast<TrustedByteArray>(*this)->AllocatedSize();
2001 }
2002 if (instance_type == FEEDBACK_METADATA_TYPE) {
2003 return UncheckedCast<FeedbackMetadata>(*this)->AllocatedSize();
2004 }
2005 if (base::IsInRange(instance_type, FIRST_DESCRIPTOR_ARRAY_TYPE,
2006 LAST_DESCRIPTOR_ARRAY_TYPE)) {
2008 UncheckedCast<DescriptorArray>(*this)->number_of_all_descriptors());
2009 }
2010 if (base::IsInRange(instance_type, FIRST_WEAK_FIXED_ARRAY_TYPE,
2011 LAST_WEAK_FIXED_ARRAY_TYPE)) {
2012 return UncheckedCast<WeakFixedArray>(*this)->AllocatedSize();
2013 }
2014 if (instance_type == WEAK_ARRAY_LIST_TYPE) {
2016 UncheckedCast<WeakArrayList>(*this)->capacity());
2017 }
2018 if (instance_type == SMALL_ORDERED_HASH_SET_TYPE) {
2020 UncheckedCast<SmallOrderedHashSet>(*this)->Capacity());
2021 }
2022 if (instance_type == SMALL_ORDERED_HASH_MAP_TYPE) {
2024 UncheckedCast<SmallOrderedHashMap>(*this)->Capacity());
2025 }
2026 if (instance_type == SMALL_ORDERED_NAME_DICTIONARY_TYPE) {
2029 }
2030 if (instance_type == SWISS_NAME_DICTIONARY_TYPE) {
2032 UncheckedCast<SwissNameDictionary>(*this)->Capacity());
2033 }
2034 if (instance_type == PROPERTY_ARRAY_TYPE) {
2037 }
2038 if (instance_type == FEEDBACK_VECTOR_TYPE) {
2039 return FeedbackVector::SizeFor(
2040 UncheckedCast<FeedbackVector>(*this)->length());
2041 }
2042 if (instance_type == BIGINT_TYPE) {
2043 return BigInt::SizeFor(UncheckedCast<BigInt>(*this)->length());
2044 }
2045 if (instance_type == PREPARSE_DATA_TYPE) {
2047 return PreparseData::SizeFor(data->data_length(), data->children_length());
2048 }
2049#define MAKE_TORQUE_SIZE_FOR(TYPE, TypeName) \
2050 if (instance_type == TYPE) { \
2051 return UncheckedCast<TypeName>(*this)->AllocatedSize(); \
2052 }
2053 TORQUE_INSTANCE_TYPE_TO_BODY_DESCRIPTOR_LIST(MAKE_TORQUE_SIZE_FOR)
2054#undef MAKE_TORQUE_SIZE_FOR
2055
2056 if (instance_type == INSTRUCTION_STREAM_TYPE) {
2057 return UncheckedCast<InstructionStream>(*this)->Size();
2058 }
2059 if (instance_type == COVERAGE_INFO_TYPE) {
2060 return CoverageInfo::SizeFor(
2061 UncheckedCast<CoverageInfo>(*this)->slot_count());
2062 }
2063#if V8_ENABLE_WEBASSEMBLY
2064 if (instance_type == WASM_TYPE_INFO_TYPE) {
2065 return WasmTypeInfo::SizeFor(
2066 UncheckedCast<WasmTypeInfo>(*this)->supertypes_length());
2067 }
2068 if (instance_type == WASM_STRUCT_TYPE) {
2069 return WasmStruct::GcSafeSize(map);
2070 }
2071 if (instance_type == WASM_ARRAY_TYPE) {
2072 return WasmArray::SizeFor(map, UncheckedCast<WasmArray>(*this)->length());
2073 }
2074 if (instance_type == WASM_NULL_TYPE) {
2075 return WasmNull::kSize;
2076 }
2077 if (instance_type == WASM_DISPATCH_TABLE_TYPE) {
2079 UncheckedCast<WasmDispatchTable>(*this)->capacity());
2080 }
2081#endif // V8_ENABLE_WEBASSEMBLY
2082 DCHECK_EQ(instance_type, EMBEDDER_DATA_ARRAY_TYPE);
2084 UncheckedCast<EmbedderDataArray>(*this)->length());
2085}
2086
2088 return NeedsRehashing(map(cage_base)->instance_type());
2089}
2090
2091bool HeapObject::NeedsRehashing(InstanceType instance_type) const {
2093 // Use map() only when it's guaranteed that it's not an InstructionStream
2094 // object.
2095 DCHECK_IMPLIES(instance_type != INSTRUCTION_STREAM_TYPE,
2096 instance_type == map()->instance_type());
2097 } else {
2098 DCHECK_EQ(instance_type, map()->instance_type());
2099 }
2100 switch (instance_type) {
2101 case DESCRIPTOR_ARRAY_TYPE:
2102 case STRONG_DESCRIPTOR_ARRAY_TYPE:
2103 return Cast<DescriptorArray>(*this)->number_of_descriptors() > 1;
2104 case TRANSITION_ARRAY_TYPE:
2105 return Cast<TransitionArray>(*this)->number_of_transitions() > 1;
2106 case ORDERED_HASH_MAP_TYPE:
2107 case ORDERED_HASH_SET_TYPE:
2108 return false; // We'll rehash from the JSMap or JSSet referencing them.
2109 case NAME_DICTIONARY_TYPE:
2110 case NAME_TO_INDEX_HASH_TABLE_TYPE:
2111 case REGISTERED_SYMBOL_TABLE_TYPE:
2112 case GLOBAL_DICTIONARY_TYPE:
2113 case NUMBER_DICTIONARY_TYPE:
2114 case SIMPLE_NUMBER_DICTIONARY_TYPE:
2115 case HASH_TABLE_TYPE:
2116 case SMALL_ORDERED_HASH_MAP_TYPE:
2117 case SMALL_ORDERED_HASH_SET_TYPE:
2118 case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
2119 case SWISS_NAME_DICTIONARY_TYPE:
2120 case JS_MAP_TYPE:
2121 case JS_SET_TYPE:
2122 return true;
2123 default:
2124 return false;
2125 }
2126 UNREACHABLE();
2127}
2128
2130 DCHECK(NeedsRehashing(cage_base));
2131 switch (map(cage_base)->instance_type()) {
2132 case JS_MAP_TYPE:
2133 case JS_SET_TYPE:
2134 return true;
2135 case ORDERED_HASH_MAP_TYPE:
2136 case ORDERED_HASH_SET_TYPE:
2137 UNREACHABLE(); // We'll rehash from the JSMap or JSSet referencing them.
2138 case ORDERED_NAME_DICTIONARY_TYPE:
2139 return false;
2140 case NAME_DICTIONARY_TYPE:
2141 case NAME_TO_INDEX_HASH_TABLE_TYPE:
2142 case REGISTERED_SYMBOL_TABLE_TYPE:
2143 case GLOBAL_DICTIONARY_TYPE:
2144 case NUMBER_DICTIONARY_TYPE:
2145 case SIMPLE_NUMBER_DICTIONARY_TYPE:
2146 case SWISS_NAME_DICTIONARY_TYPE:
2147 return true;
2148 case DESCRIPTOR_ARRAY_TYPE:
2149 case STRONG_DESCRIPTOR_ARRAY_TYPE:
2150 return true;
2151 case TRANSITION_ARRAY_TYPE:
2152 return true;
2153 case SMALL_ORDERED_HASH_MAP_TYPE:
2154 return Cast<SmallOrderedHashMap>(*this)->NumberOfElements() == 0;
2155 case SMALL_ORDERED_HASH_SET_TYPE:
2156 return Cast<SmallOrderedHashMap>(*this)->NumberOfElements() == 0;
2157 case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
2158 return Cast<SmallOrderedNameDictionary>(*this)->NumberOfElements() == 0;
2159 default:
2160 return false;
2161 }
2162 UNREACHABLE();
2163}
2164
2165template <typename IsolateT>
2166void HeapObject::RehashBasedOnMap(IsolateT* isolate) {
2167 switch (map(isolate)->instance_type()) {
2168 case HASH_TABLE_TYPE:
2169 Cast<ObjectHashTable>(*this)->Rehash(isolate);
2170 break;
2171 case NAME_DICTIONARY_TYPE:
2172 Cast<NameDictionary>(*this)->Rehash(isolate);
2173 break;
2174 case NAME_TO_INDEX_HASH_TABLE_TYPE:
2175 Cast<NameToIndexHashTable>(*this)->Rehash(isolate);
2176 break;
2177 case REGISTERED_SYMBOL_TABLE_TYPE:
2178 Cast<RegisteredSymbolTable>(*this)->Rehash(isolate);
2179 break;
2180 case SWISS_NAME_DICTIONARY_TYPE:
2181 Cast<SwissNameDictionary>(*this)->Rehash(isolate);
2182 break;
2183 case GLOBAL_DICTIONARY_TYPE:
2184 Cast<GlobalDictionary>(*this)->Rehash(isolate);
2185 break;
2186 case NUMBER_DICTIONARY_TYPE:
2187 Cast<NumberDictionary>(*this)->Rehash(isolate);
2188 break;
2189 case SIMPLE_NUMBER_DICTIONARY_TYPE:
2190 Cast<SimpleNumberDictionary>(*this)->Rehash(isolate);
2191 break;
2192 case DESCRIPTOR_ARRAY_TYPE:
2193 case STRONG_DESCRIPTOR_ARRAY_TYPE:
2194 DCHECK_LE(1, Cast<DescriptorArray>(*this)->number_of_descriptors());
2195 Cast<DescriptorArray>(*this)->Sort();
2196 break;
2197 case TRANSITION_ARRAY_TYPE:
2198 Cast<TransitionArray>(*this)->Sort();
2199 break;
2200 case SMALL_ORDERED_HASH_MAP_TYPE:
2201 DCHECK_EQ(0, Cast<SmallOrderedHashMap>(*this)->NumberOfElements());
2202 break;
2203 case SMALL_ORDERED_HASH_SET_TYPE:
2204 DCHECK_EQ(0, Cast<SmallOrderedHashSet>(*this)->NumberOfElements());
2205 break;
2206 case ORDERED_HASH_MAP_TYPE:
2207 case ORDERED_HASH_SET_TYPE:
2208 UNREACHABLE(); // We'll rehash from the JSMap or JSSet referencing them.
2209 case JS_MAP_TYPE: {
2210 Cast<JSMap>(*this)->Rehash(isolate->AsIsolate());
2211 break;
2212 }
2213 case JS_SET_TYPE: {
2214 Cast<JSSet>(*this)->Rehash(isolate->AsIsolate());
2215 break;
2216 }
2217 case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
2218 DCHECK_EQ(0, Cast<SmallOrderedNameDictionary>(*this)->NumberOfElements());
2219 break;
2222 // Rare case, rehash read-only space strings before they are sealed.
2224 Cast<String>(*this)->EnsureHash();
2225 break;
2226 default:
2227 // TODO(ishell): remove once b/326043780 is no longer an issue.
2228 isolate->AsIsolate()->PushParamsAndDie(
2229 reinterpret_cast<void*>(ptr()), reinterpret_cast<void*>(map().ptr()),
2230 reinterpret_cast<void*>(
2231 static_cast<uintptr_t>(map()->instance_type())));
2232 UNREACHABLE();
2233 }
2234}
2235template void HeapObject::RehashBasedOnMap(Isolate* isolate);
2236template void HeapObject::RehashBasedOnMap(LocalIsolate* isolate);
2237
2238void DescriptorArray::GeneralizeAllFields(bool clear_constness) {
2239 int length = number_of_descriptors();
2240 for (InternalIndex i : InternalIndex::Range(length)) {
2241 PropertyDetails details = GetDetails(i);
2243 if (details.location() == PropertyLocation::kField) {
2244 // Since constness is not propagated across proto transitions we must
2245 // clear the flag here.
2246 if (clear_constness) {
2248 }
2251 }
2252 SetDetails(i, details);
2253 }
2254}
2255
2257 DirectHandle<JSAny> object,
2258 DirectHandle<Name> name,
2260 StoreOrigin store_origin,
2261 Maybe<ShouldThrow> should_throw) {
2262 LookupIterator it(isolate, object, name);
2263 MAYBE_RETURN_NULL(SetProperty(&it, value, store_origin, should_throw));
2264 return indirect_handle(value, isolate);
2265}
2266
2269 Maybe<ShouldThrow> should_throw,
2270 StoreOrigin store_origin, bool* found) {
2271 it->UpdateProtector();
2272 DCHECK(it->IsFound());
2273
2274 // Make sure that the top context does not change when doing callbacks or
2275 // interceptor calls.
2276 AssertNoContextChange ncc(it->isolate());
2277
2278 for (;; it->Next()) {
2279 switch (it->state()) {
2281 if (it->HasAccess()) continue;
2282 // Check whether it makes sense to reuse the lookup iterator. Here it
2283 // might still call into setters up the prototype chain.
2285 should_throw);
2286
2288 DirectHandle<JSAny> receiver = it->GetReceiver();
2289 // In case of global IC, the receiver is the global object. Replace by
2290 // the global proxy.
2291 if (IsJSGlobalObject(*receiver)) {
2293 Cast<JSGlobalObject>(*receiver)->global_proxy(), it->isolate());
2294 }
2295 return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(),
2296 value, receiver, should_throw);
2297 }
2298
2300 RETURN_FAILURE(it->isolate(), kThrowOnError,
2301 NewTypeError(MessageTemplate::kWasmObjectsAreOpaque));
2302
2304 if (it->HolderIsReceiverOrHiddenPrototype()) {
2306 if (!JSObject::SetPropertyWithInterceptor(it, should_throw, value)
2307 .To(&result)) {
2308 // An exception was thrown in the interceptor. Propagate.
2309 return Nothing<bool>();
2310 }
2311 switch (result) {
2313 return Just(false);
2315 return Just(true);
2317 // Proceed lookup.
2318 break;
2319 }
2320 // Assuming that the callback has side effects, we use
2321 // Object::SetSuperProperty() which works properly regardless on
2322 // whether the property was present on the receiver or not when
2323 // storing to the receiver.
2324 // Proceed lookup from the next state.
2325 it->Next();
2326 } else {
2327 Maybe<PropertyAttributes> maybe_attributes =
2329 if (maybe_attributes.IsNothing()) return Nothing<bool>();
2330 if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
2331 return WriteToReadOnlyProperty(it, value, should_throw);
2332 }
2333 // At this point we might have called interceptor's query or getter
2334 // callback. Assuming that the callbacks have side effects, we use
2335 // Object::SetSuperProperty() which works properly regardless on
2336 // whether the property was present on the receiver or not when
2337 // storing to the receiver.
2338 if (maybe_attributes.FromJust() == ABSENT) {
2339 // Proceed lookup from the next state.
2340 it->Next();
2341 } else {
2342 // Finish lookup in order to make Object::SetSuperProperty() store
2343 // property to the receiver.
2344 it->NotFound();
2345 }
2346 }
2347 return Object::SetSuperProperty(it, value, store_origin, should_throw);
2348 }
2349
2351 if (it->IsReadOnly()) {
2352 return WriteToReadOnlyProperty(it, value, should_throw);
2353 }
2354 DirectHandle<Object> accessors = it->GetAccessors();
2355 if (IsAccessorInfo(*accessors) &&
2356 !it->HolderIsReceiverOrHiddenPrototype()) {
2357 *found = false;
2358 return Nothing<bool>();
2359 }
2360 return SetPropertyWithAccessor(it, value, should_throw);
2361 }
2363 // IntegerIndexedElementSet converts value to a Number/BigInt prior to
2364 // the bounds check. The bounds check has already happened here, but
2365 // perform the possibly effectful ToNumber (or ToBigInt) operation
2366 // anyways.
2367 DirectHandle<JSTypedArray> holder = it->GetHolder<JSTypedArray>();
2368 DirectHandle<Object> converted_value;
2369 if (holder->type() == kExternalBigInt64Array ||
2370 holder->type() == kExternalBigUint64Array) {
2372 it->isolate(), converted_value,
2373 BigInt::FromObject(it->isolate(), value), Nothing<bool>());
2374 } else {
2376 it->isolate(), converted_value,
2377 Object::ToNumber(it->isolate(), value), Nothing<bool>());
2378 }
2379
2380 // For RAB/GSABs, the above conversion might grow the buffer so that the
2381 // index is no longer out of bounds. Redo the bounds check and try
2382 // again.
2383 it->RecheckTypedArrayBounds();
2384 if (it->state() != LookupIterator::DATA) {
2385 // Still out of bounds.
2387
2388 // FIXME: Throw a TypeError if the holder is detached here
2389 // (IntegerIndexedElementSet step 5).
2390
2391 // TODO(verwaest): Per spec, we should return false here (steps 6-9
2392 // in IntegerIndexedElementSet), resulting in an exception being
2393 // thrown on OOB accesses in strict code. Historically, v8 has not
2394 // done made this change due to uncertainty about web compat.
2395 // (v8:4901)
2396 return Just(true);
2397 }
2398 value = converted_value;
2399 [[fallthrough]];
2400 }
2401
2403 if (it->IsReadOnly()) {
2404 return WriteToReadOnlyProperty(it, value, should_throw);
2405 }
2406 if (it->HolderIsReceiverOrHiddenPrototype()) {
2407 return SetDataProperty(it, value);
2408 }
2409 [[fallthrough]];
2412 *found = false;
2413 return Nothing<bool>();
2414 }
2415 UNREACHABLE();
2416 }
2417}
2418
2420 LookupIterator* it, Maybe<ShouldThrow> should_throw) {
2421 Isolate* isolate = it->isolate();
2422
2423 if (IsJSGlobalObject(*it->GetReceiver(), isolate) &&
2424 (GetShouldThrow(isolate, should_throw) == ShouldThrow::kThrowOnError)) {
2425 if (it->state() == LookupIterator::TRANSITION) {
2426 // The property cell that we have created is garbage because we are going
2427 // to throw now instead of putting it into the global dictionary. However,
2428 // the cell might already have been stored into the feedback vector, so
2429 // we must invalidate it nevertheless.
2430 it->transition_cell()->ClearAndInvalidate(isolate);
2431 }
2432 isolate->Throw(*isolate->factory()->NewReferenceError(
2433 MessageTemplate::kNotDefined, it->GetName()));
2434 return false;
2435 }
2436 return true;
2437}
2438
2440 StoreOrigin store_origin,
2441 Maybe<ShouldThrow> should_throw) {
2442 if (it->IsFound()) {
2443 bool found = true;
2445 SetPropertyInternal(it, value, should_throw, store_origin, &found);
2446 if (found) return result;
2447 }
2448
2449 if (!CheckContextualStoreToJSGlobalObject(it, should_throw)) {
2450 return Nothing<bool>();
2451 }
2452 return AddDataProperty(it, value, NONE, should_throw, store_origin);
2453}
2454
2457 StoreOrigin store_origin,
2458 Maybe<ShouldThrow> should_throw) {
2459 Isolate* isolate = it->isolate();
2460
2461 if (it->IsFound()) {
2462 bool found = true;
2464 SetPropertyInternal(it, value, should_throw, store_origin, &found);
2465 if (found) return result;
2466 }
2467
2468 it->UpdateProtector();
2469
2470 // The property either doesn't exist on the holder or exists there as a data
2471 // property.
2472
2473 if (!IsJSReceiver(*it->GetReceiver())) {
2474 return WriteToReadOnlyProperty(it, value, should_throw);
2475 }
2477
2478 // Note, the callers rely on the fact that this code is redoing the full own
2479 // lookup from scratch.
2480 LookupIterator own_lookup(isolate, receiver, it->GetKey(),
2482 for (;; own_lookup.Next()) {
2483 switch (own_lookup.state()) {
2485 if (!own_lookup.HasAccess()) {
2486 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
2487 should_throw);
2488 }
2489 continue;
2490
2492 if (IsAccessorInfo(*own_lookup.GetAccessors())) {
2493 if (own_lookup.IsReadOnly()) {
2494 return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
2495 }
2496 return Object::SetPropertyWithAccessor(&own_lookup, value,
2497 should_throw);
2498 }
2499 [[fallthrough]];
2501 return RedefineIncompatibleProperty(isolate, it->GetName(), value,
2502 should_throw);
2503
2504 case LookupIterator::DATA: {
2505 if (own_lookup.IsReadOnly()) {
2506 return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
2507 }
2508 return SetDataProperty(&own_lookup, value);
2509 }
2510
2513 PropertyDescriptor desc;
2514 Maybe<bool> owned =
2515 JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
2516 MAYBE_RETURN(owned, Nothing<bool>());
2517 if (!owned.FromJust()) {
2518 // |own_lookup| might become outdated at this point anyway.
2519 // TODO(leszeks): Remove this restart since we don't really use the
2520 // lookup iterator after this.
2521 own_lookup.Restart();
2522 if (!CheckContextualStoreToJSGlobalObject(&own_lookup,
2523 should_throw)) {
2524 return Nothing<bool>();
2525 }
2526 return JSReceiver::CreateDataProperty(isolate, receiver, it->GetKey(),
2527 value, should_throw);
2528 }
2530 !desc.writable()) {
2531 return RedefineIncompatibleProperty(isolate, it->GetName(), value,
2532 should_throw);
2533 }
2534
2535 PropertyDescriptor value_desc;
2536 value_desc.set_value(Cast<JSAny>(value));
2537 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
2538 &value_desc, should_throw);
2539 }
2540
2542 if (!CheckContextualStoreToJSGlobalObject(&own_lookup, should_throw)) {
2543 return Nothing<bool>();
2544 }
2545 return AddDataProperty(&own_lookup, value, NONE, should_throw,
2546 store_origin);
2547
2549 RETURN_FAILURE(it->isolate(), kThrowOnError,
2550 NewTypeError(MessageTemplate::kWasmObjectsAreOpaque));
2551
2553 UNREACHABLE();
2554 }
2555 UNREACHABLE();
2556 }
2557}
2558
2563 Maybe<ShouldThrow> should_throw) {
2565 isolate, GetShouldThrow(isolate, should_throw),
2566 NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
2567 Object::TypeOf(isolate, receiver), receiver));
2568}
2569
2572 Maybe<ShouldThrow> maybe_should_throw) {
2573 ShouldThrow should_throw = GetShouldThrow(it->isolate(), maybe_should_throw);
2574 if (it->IsFound() && !it->HolderIsReceiver()) {
2575 // "Override mistake" attempted, record a use count to track this per
2576 // v8:8175
2578 should_throw == kThrowOnError
2581 it->isolate()->CountUsage(feature);
2582 }
2583 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
2584 it->GetName(), value, should_throw);
2585}
2586
2591 ShouldThrow should_throw) {
2592 RETURN_FAILURE(isolate, should_throw,
2593 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
2594 Object::TypeOf(isolate, receiver), receiver));
2595}
2596
2599 Maybe<ShouldThrow> should_throw) {
2600 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
2601 NewTypeError(MessageTemplate::kRedefineDisallowed, name));
2602}
2603
2605 DirectHandle<Object> value) {
2606 Isolate* isolate = it->isolate();
2607 DCHECK_IMPLIES(IsJSProxy(*it->GetReceiver(), isolate),
2608 it->GetName()->IsPrivateName());
2609 DCHECK_IMPLIES(!it->IsElement() && it->GetName()->IsPrivateName(),
2610 it->state() == LookupIterator::DATA);
2612
2613 // Store on the holder which may be hidden behind the receiver.
2614 DCHECK(it->HolderIsReceiverOrHiddenPrototype());
2615
2616 DirectHandle<Object> to_assign = value;
2617 // Convert the incoming value to a number for storing into typed arrays.
2618 if (it->IsElement() && IsJSObject(*receiver, isolate) &&
2619 Cast<JSObject>(*receiver)->HasTypedArrayOrRabGsabTypedArrayElements(
2620 isolate)) {
2621 auto receiver_ta = Cast<JSTypedArray>(receiver);
2622 ElementsKind elements_kind = Cast<JSObject>(*receiver)->GetElementsKind();
2623 if (IsBigIntTypedArrayElementsKind(elements_kind)) {
2624 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, to_assign,
2625 BigInt::FromObject(isolate, value),
2626 Nothing<bool>());
2627 if (V8_UNLIKELY(receiver_ta->IsDetachedOrOutOfBounds() ||
2628 it->index() >= receiver_ta->GetLength())) {
2629 return Just(true);
2630 }
2631 } else if (!IsNumber(*value) && !IsUndefined(*value, isolate)) {
2632 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, to_assign,
2633 Object::ToNumber(isolate, value),
2634 Nothing<bool>());
2635 if (V8_UNLIKELY(receiver_ta->IsDetachedOrOutOfBounds() ||
2636 it->index() >= receiver_ta->GetLength())) {
2637 return Just(true);
2638 }
2639 }
2640 }
2641
2642 DCHECK(!IsWasmObject(*receiver, isolate));
2643 if (V8_UNLIKELY(IsJSSharedStruct(*receiver, isolate) ||
2644 IsJSSharedArray(*receiver, isolate))) {
2645 // Shared structs can only point to primitives or shared values.
2647 isolate, to_assign, Object::Share(isolate, to_assign, kThrowOnError),
2648 Nothing<bool>());
2649 it->WriteDataValue(to_assign, false);
2650 } else {
2651 // Possibly migrate to the most up-to-date map that will be able to store
2652 // |value| under it->name().
2653 it->PrepareForDataProperty(to_assign);
2654
2655 // Write the property value.
2656 it->WriteDataValue(to_assign, false);
2657 }
2658
2659#if VERIFY_HEAP
2660 if (v8_flags.verify_heap) {
2661 receiver->HeapObjectVerify(isolate);
2662 }
2663#endif
2664 return Just(true);
2665}
2666
2669 PropertyAttributes attributes,
2670 Maybe<ShouldThrow> should_throw,
2671 StoreOrigin store_origin,
2672 EnforceDefineSemantics semantics) {
2673 if (!IsJSReceiver(*it->GetReceiver())) {
2674 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
2675 value, should_throw);
2676 }
2677
2678 // Private symbols should be installed on JSProxy using
2679 // JSProxy::SetPrivateSymbol.
2680 if (IsJSProxy(*it->GetReceiver()) && it->GetName()->IsPrivate() &&
2681 !it->GetName()->IsPrivateName()) {
2682 RETURN_FAILURE(it->isolate(), GetShouldThrow(it->isolate(), should_throw),
2683 NewTypeError(MessageTemplate::kProxyPrivate));
2684 }
2685
2687
2688 DirectHandle<JSReceiver> receiver = it->GetStoreTarget<JSReceiver>();
2689 DCHECK_IMPLIES(IsJSProxy(*receiver), it->GetName()->IsPrivateName());
2690 DCHECK_IMPLIES(IsJSProxy(*receiver),
2691 it->state() == LookupIterator::NOT_FOUND);
2692
2693 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
2694 // instead. If the prototype is Null, the proxy is detached.
2695 if (IsJSGlobalProxy(*receiver)) return Just(true);
2696
2697 Isolate* isolate = it->isolate();
2698
2699 if (it->ExtendingNonExtensible(receiver)) {
2700 bool is_shared_object = IsAlwaysSharedSpaceJSObject(*receiver);
2702 isolate, GetShouldThrow(it->isolate(), should_throw),
2703 NewTypeError(
2705 ? (is_shared_object
2706 ? MessageTemplate::kDefineDisallowedFixedLayout
2707 : MessageTemplate::kDefineDisallowed)
2708 : (is_shared_object ? MessageTemplate::kObjectFixedLayout
2709 : MessageTemplate::kObjectNotExtensible),
2710 it->GetName()));
2711 }
2712
2713 if (it->IsElement(*receiver)) {
2714 if (IsJSArray(*receiver)) {
2716 if (JSArray::WouldChangeReadOnlyLength(array, it->array_index())) {
2717 RETURN_FAILURE(isolate, GetShouldThrow(it->isolate(), should_throw),
2718 NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
2719 isolate->factory()->length_string(),
2720 Object::TypeOf(isolate, array), array));
2721 }
2722 }
2723
2725 MAYBE_RETURN(JSObject::AddDataElement(receiver_obj, it->array_index(),
2726 value, attributes),
2727 Nothing<bool>());
2728 JSObject::ValidateElements(*receiver_obj);
2729 return Just(true);
2730 }
2731
2732 return Object::TransitionAndWriteDataProperty(it, value, attributes,
2733 should_throw, store_origin);
2734}
2735
2736// static
2739 PropertyAttributes attributes, Maybe<ShouldThrow> should_throw,
2740 StoreOrigin store_origin) {
2741 DirectHandle<JSReceiver> receiver = it->GetStoreTarget<JSReceiver>();
2742 it->UpdateProtector();
2743 // Migrate to the most up-to-date map that will be able to store |value|
2744 // under it->name() with |attributes|.
2745 it->PrepareTransitionToDataProperty(receiver, value, attributes,
2746 store_origin);
2748 it->ApplyTransitionToDataProperty(receiver);
2749
2750 // Write the property value.
2751 it->WriteDataValue(value, true);
2752
2753#if VERIFY_HEAP
2754 if (v8_flags.verify_heap) {
2755 receiver->HeapObjectVerify(it->isolate());
2756 }
2757#endif
2758
2759 return Just(true);
2760}
2761
2762// static
2763template <template <typename> typename HandleType>
2764 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
2765typename HandleType<Object>::MaybeType Object::ShareSlow(
2766 Isolate* isolate, HandleType<HeapObject> value,
2767 ShouldThrow throw_if_cannot_be_shared) {
2768 // Use Object::Share() if value might already be shared.
2769 DCHECK(!IsShared(*value));
2770
2771 SharedObjectSafePublishGuard publish_guard;
2772
2773 if (IsString(*value)) {
2774 return String::Share(isolate, Cast<String>(value));
2775 }
2776
2777 if (IsHeapNumber(*value)) {
2778 uint64_t bits = Cast<HeapNumber>(*value)->value_as_bits();
2779 return isolate->factory()
2780 ->NewHeapNumberFromBits<AllocationType::kSharedOld>(bits);
2781 }
2782
2783 if (throw_if_cannot_be_shared == kThrowOnError) {
2784 THROW_NEW_ERROR(isolate,
2785 NewTypeError(MessageTemplate::kCannotBeShared, value));
2786 }
2787 return {};
2788}
2789
2791 Isolate* isolate, DirectHandle<HeapObject> value,
2792 ShouldThrow throw_if_cannot_be_shared);
2794 Isolate* isolate, IndirectHandle<HeapObject> value,
2795 ShouldThrow throw_if_cannot_be_shared);
2796
2797namespace {
2798
2799template <class T>
2800int AppendUniqueCallbacks(Isolate* isolate, DirectHandle<ArrayList> callbacks,
2802 int valid_descriptors) {
2803 int nof_callbacks = callbacks->length();
2804
2805 // Fill in new callback descriptors. Process the callbacks from
2806 // back to front so that the last callback with a given name takes
2807 // precedence over previously added callbacks with that name.
2808 for (int i = nof_callbacks - 1; i >= 0; i--) {
2809 DirectHandle<AccessorInfo> entry(Cast<AccessorInfo>(callbacks->get(i)),
2810 isolate);
2811 DirectHandle<Name> key(Cast<Name>(entry->name()), isolate);
2813 // Check if a descriptor with this name already exists before writing.
2814 if (!T::Contains(key, entry, valid_descriptors, array)) {
2815 T::Insert(key, entry, valid_descriptors, array);
2816 valid_descriptors++;
2817 }
2818 }
2819
2820 return valid_descriptors;
2821}
2822
2823struct FixedArrayAppender {
2824 using Array = FixedArray;
2825 static bool Contains(DirectHandle<Name> key, DirectHandle<AccessorInfo> entry,
2826 int valid_descriptors, DirectHandle<FixedArray> array) {
2827 for (int i = 0; i < valid_descriptors; i++) {
2828 if (*key == Cast<AccessorInfo>(array->get(i))->name()) return true;
2829 }
2830 return false;
2831 }
2832 static void Insert(DirectHandle<Name> key, DirectHandle<AccessorInfo> entry,
2833 int valid_descriptors, DirectHandle<FixedArray> array) {
2835 array->set(valid_descriptors, *entry);
2836 }
2837};
2838
2839} // namespace
2840
2842 DirectHandle<Object> descriptors,
2844 int valid_descriptors) {
2845 auto callbacks = Cast<ArrayList>(descriptors);
2846 DCHECK_GE(array->length(), callbacks->length() + valid_descriptors);
2847 return AppendUniqueCallbacks<FixedArrayAppender>(isolate, callbacks, array,
2848 valid_descriptors);
2849}
2850
2852 Isolate* isolate = proxy->GetIsolate();
2853 // ES#sec-proxy-revocation-functions
2854 if (!proxy->IsRevoked()) {
2855 // 5. Set p.[[ProxyTarget]] to null.
2856 proxy->set_target(ReadOnlyRoots(isolate).null_value());
2857 // 6. Set p.[[ProxyHandler]] to null.
2858 proxy->set_handler(ReadOnlyRoots(isolate).null_value());
2859 }
2860 DCHECK(proxy->IsRevoked());
2861}
2862
2863// static
2865 Isolate* isolate = proxy->GetIsolate();
2867 for (int i = 0; i < JSProxy::kMaxIterationLimit; i++) {
2868 proxy = Cast<JSProxy>(object);
2869 if (proxy->IsRevoked()) {
2870 isolate->Throw(*isolate->factory()->NewTypeError(
2871 MessageTemplate::kProxyRevoked,
2872 isolate->factory()->NewStringFromAsciiChecked("IsArray")));
2873 return Nothing<bool>();
2874 }
2875 object = direct_handle(Cast<JSReceiver>(proxy->target()), isolate);
2876 if (IsJSArray(*object)) return Just(true);
2877 if (!IsJSProxy(*object)) return Just(false);
2878 }
2879
2880 // Too deep recursion, throw a RangeError.
2881 isolate->StackOverflow();
2882 return Nothing<bool>();
2883}
2884
2886 DirectHandle<Name> name) {
2887 DCHECK(!name->IsPrivate());
2888 STACK_CHECK(isolate, Nothing<bool>());
2889 // 1. (Assert)
2890 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
2891 DirectHandle<Object> handler(proxy->handler(), isolate);
2892 // 3. If handler is null, throw a TypeError exception.
2893 // 4. Assert: Type(handler) is Object.
2894 if (proxy->IsRevoked()) {
2895 isolate->Throw(*isolate->factory()->NewTypeError(
2896 MessageTemplate::kProxyRevoked, isolate->factory()->has_string()));
2897 return Nothing<bool>();
2898 }
2899 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
2900 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
2901 // 6. Let trap be ? GetMethod(handler, "has").
2904 isolate, trap,
2905 Object::GetMethod(isolate, Cast<JSReceiver>(handler),
2906 isolate->factory()->has_string()),
2907 Nothing<bool>());
2908 // 7. If trap is undefined, then
2909 if (IsUndefined(*trap, isolate)) {
2910 // 7a. Return target.[[HasProperty]](P).
2911 return JSReceiver::HasProperty(isolate, target, name);
2912 }
2913 // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, P»)).
2914 DirectHandle<Object> trap_result_obj;
2915 DirectHandle<Object> args[] = {target, name};
2917 isolate, trap_result_obj,
2918 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
2919 Nothing<bool>());
2920 bool boolean_trap_result = Object::BooleanValue(*trap_result_obj, isolate);
2921 // 9. If booleanTrapResult is false, then:
2922 if (!boolean_trap_result) {
2923 MAYBE_RETURN(JSProxy::CheckHasTrap(isolate, name, target), Nothing<bool>());
2924 }
2925 // 10. Return booleanTrapResult.
2926 return Just(boolean_trap_result);
2927}
2928
2930 DirectHandle<JSReceiver> target) {
2931 // 9a. Let targetDesc be ? target.[[GetOwnProperty]](P).
2932 PropertyDescriptor target_desc;
2933 Maybe<bool> target_found =
2934 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
2935 MAYBE_RETURN(target_found, Nothing<bool>());
2936 // 9b. If targetDesc is not undefined, then:
2937 if (target_found.FromJust()) {
2938 // 9b i. If targetDesc.[[Configurable]] is false, throw a TypeError
2939 // exception.
2940 if (!target_desc.configurable()) {
2941 isolate->Throw(*isolate->factory()->NewTypeError(
2942 MessageTemplate::kProxyHasNonConfigurable, name));
2943 return Nothing<bool>();
2944 }
2945 // 9b ii. Let extensibleTarget be ? IsExtensible(target).
2946 Maybe<bool> extensible_target = JSReceiver::IsExtensible(isolate, target);
2947 MAYBE_RETURN(extensible_target, Nothing<bool>());
2948 // 9b iii. If extensibleTarget is false, throw a TypeError exception.
2949 if (!extensible_target.FromJust()) {
2950 isolate->Throw(*isolate->factory()->NewTypeError(
2951 MessageTemplate::kProxyHasNonExtensible, name));
2952 return Nothing<bool>();
2953 }
2954 }
2955 return Just(true);
2956}
2957
2959 DirectHandle<Name> name,
2962 Maybe<ShouldThrow> should_throw) {
2963 DCHECK(!name->IsPrivate());
2964 Isolate* isolate = proxy->GetIsolate();
2965 STACK_CHECK(isolate, Nothing<bool>());
2966 Factory* factory = isolate->factory();
2967 DirectHandle<String> trap_name = factory->set_string();
2968
2969 if (proxy->IsRevoked()) {
2970 isolate->Throw(
2971 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
2972 return Nothing<bool>();
2973 }
2974 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
2975 DirectHandle<JSReceiver> handler(Cast<JSReceiver>(proxy->handler()), isolate);
2976
2979 isolate, trap, Object::GetMethod(isolate, handler, trap_name),
2980 Nothing<bool>());
2981 if (IsUndefined(*trap, isolate)) {
2982 PropertyKey key(isolate, name);
2983 LookupIterator it(isolate, receiver, key, target);
2984
2986 should_throw);
2987 }
2988
2989 DirectHandle<Object> trap_result;
2992 isolate, trap_result,
2993 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
2994 Nothing<bool>());
2995 if (!Object::BooleanValue(*trap_result, isolate)) {
2996 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
2997 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
2998 trap_name, name));
2999 }
3000
3002 JSProxy::CheckGetSetTrapResult(isolate, name, target, value, kSet);
3003
3004 if (result.is_null()) {
3005 return Nothing<bool>();
3006 }
3007 return Just(true);
3008}
3009
3011 DirectHandle<Name> name,
3012 LanguageMode language_mode) {
3013 DCHECK(!name->IsPrivate());
3014 ShouldThrow should_throw =
3015 is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
3016 Isolate* isolate = proxy->GetIsolate();
3017 STACK_CHECK(isolate, Nothing<bool>());
3018 Factory* factory = isolate->factory();
3019 DirectHandle<String> trap_name = factory->deleteProperty_string();
3020
3021 if (proxy->IsRevoked()) {
3022 isolate->Throw(
3023 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
3024 return Nothing<bool>();
3025 }
3026 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
3027 DirectHandle<JSReceiver> handler(Cast<JSReceiver>(proxy->handler()), isolate);
3028
3031 isolate, trap, Object::GetMethod(isolate, handler, trap_name),
3032 Nothing<bool>());
3033 if (IsUndefined(*trap, isolate)) {
3034 return JSReceiver::DeletePropertyOrElement(isolate, target, name,
3035 language_mode);
3036 }
3037
3038 DirectHandle<Object> trap_result;
3039 DirectHandle<Object> args[] = {target, name};
3041 isolate, trap_result,
3042 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
3043 Nothing<bool>());
3044 if (!Object::BooleanValue(*trap_result, isolate)) {
3045 RETURN_FAILURE(isolate, should_throw,
3046 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
3047 trap_name, name));
3048 }
3049
3050 // Enforce the invariant.
3051 return JSProxy::CheckDeleteTrap(isolate, name, target);
3052}
3053
3055 DirectHandle<JSReceiver> target) {
3056 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
3057 PropertyDescriptor target_desc;
3058 Maybe<bool> target_found =
3059 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
3060 MAYBE_RETURN(target_found, Nothing<bool>());
3061 // 11. If targetDesc is undefined, return true.
3062 if (target_found.FromJust()) {
3063 // 12. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
3064 if (!target_desc.configurable()) {
3065 isolate->Throw(*isolate->factory()->NewTypeError(
3066 MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
3067 return Nothing<bool>();
3068 }
3069 // 13. Let extensibleTarget be ? IsExtensible(target).
3070 Maybe<bool> extensible_target = JSReceiver::IsExtensible(isolate, target);
3071 MAYBE_RETURN(extensible_target, Nothing<bool>());
3072 // 14. If extensibleTarget is false, throw a TypeError exception.
3073 if (!extensible_target.FromJust()) {
3074 isolate->Throw(*isolate->factory()->NewTypeError(
3075 MessageTemplate::kProxyDeletePropertyNonExtensible, name));
3076 return Nothing<bool>();
3077 }
3078 }
3079 return Just(true);
3080}
3081
3082// static
3084 DirectHandle<Object> target,
3085 DirectHandle<Object> handler) {
3086 if (!IsJSReceiver(*target)) {
3087 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject));
3088 }
3089 if (!IsJSReceiver(*handler)) {
3090 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyNonObject));
3091 }
3092 return isolate->factory()->NewJSProxy(Cast<JSReceiver>(target),
3093 Cast<JSReceiver>(handler));
3094}
3095
3097 PropertyDescriptor desc;
3099 it->isolate(), it->GetHolder<JSProxy>(), it->GetName(), &desc);
3101 if (!found.FromJust()) return Just(ABSENT);
3102 return Just(desc.ToAttributes());
3103}
3104
3105// TODO(jkummerow): Consider unification with FastAsArrayLength() in
3106// accessors.cc.
3107bool PropertyKeyToArrayLength(DirectHandle<Object> value, uint32_t* length) {
3108 DCHECK(IsNumber(*value) || IsName(*value));
3109 if (Object::ToArrayLength(*value, length)) return true;
3110 if (IsString(*value)) return Cast<String>(*value)->AsArrayIndex(length);
3111 return false;
3112}
3113
3114bool PropertyKeyToArrayIndex(DirectHandle<Object> index_obj, uint32_t* output) {
3115 return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32;
3116}
3117
3118// ES6 9.4.2.1
3119// static
3123 PropertyDescriptor* desc,
3124 Maybe<ShouldThrow> should_throw) {
3125 if (IsName(*name)) {
3126 name = isolate->factory()->InternalizeName(Cast<Name>(name));
3127 }
3128
3129 // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
3130 // 2. If P is "length", then:
3131 if (*name == ReadOnlyRoots(isolate).length_string()) {
3132 // 2a. Return ArraySetLength(A, Desc).
3133 return ArraySetLength(isolate, o, desc, should_throw);
3134 }
3135 // 3. Else if P is an array index, then:
3136 uint32_t index = 0;
3137 if (PropertyKeyToArrayIndex(name, &index)) {
3138 // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
3139 PropertyDescriptor old_len_desc;
3140 Maybe<bool> success = GetOwnPropertyDescriptor(
3141 isolate, o, isolate->factory()->length_string(), &old_len_desc);
3142 // 3b. (Assert)
3143 DCHECK(success.FromJust());
3144 USE(success);
3145 // 3c. Let oldLen be oldLenDesc.[[Value]].
3146 uint32_t old_len = 0;
3147 CHECK(Object::ToArrayLength(*old_len_desc.value(), &old_len));
3148 // 3d. Let index be ToUint32(P).
3149 // (Already done above.)
3150 // 3e. (Assert)
3151 // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false,
3152 // return false.
3153 if (index >= old_len && old_len_desc.has_writable() &&
3154 !old_len_desc.writable()) {
3155 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
3156 NewTypeError(MessageTemplate::kDefineDisallowed, name));
3157 }
3158 // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc).
3159 Maybe<bool> succeeded =
3160 OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
3161 // 3h. Assert: succeeded is not an abrupt completion.
3162 // In our case, if should_throw == kThrowOnError, it can be!
3163 // 3i. If succeeded is false, return false.
3164 if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded;
3165 // 3j. If index >= oldLen, then:
3166 if (index >= old_len) {
3167 // 3j i. Set oldLenDesc.[[Value]] to index + 1.
3168 old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1));
3169 // 3j ii. Let succeeded be
3170 // OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
3171 succeeded = OrdinaryDefineOwnProperty(isolate, o,
3172 isolate->factory()->length_string(),
3173 &old_len_desc, should_throw);
3174 // 3j iii. Assert: succeeded is true.
3175 DCHECK(succeeded.FromJust());
3176 USE(succeeded);
3177 }
3178 // 3k. Return true.
3179 return Just(true);
3180 }
3181
3182 // 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
3183 return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw);
3184}
3185
3186// Part of ES6 9.4.2.4 ArraySetLength.
3187// static
3189 DirectHandle<Object> length_object,
3190 uint32_t* output) {
3191 // Fast path: check numbers and strings that can be converted directly
3192 // and unobservably.
3193 if (Object::ToArrayLength(*length_object, output)) return true;
3194 if (IsString(*length_object) &&
3195 Cast<String>(length_object)->AsArrayIndex(output)) {
3196 return true;
3197 }
3198 // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength".
3199 // 3. Let newLen be ToUint32(Desc.[[Value]]).
3200 DirectHandle<Number> uint32_v;
3201 if (!Object::ToUint32(isolate, length_object).ToHandle(&uint32_v)) {
3202 // 4. ReturnIfAbrupt(newLen).
3203 return false;
3204 }
3205 // 5. Let numberLen be ToNumber(Desc.[[Value]]).
3206 DirectHandle<Number> number_v;
3207 if (!Object::ToNumber(isolate, length_object).ToHandle(&number_v)) {
3208 // 6. ReturnIfAbrupt(newLen).
3209 return false;
3210 }
3211 // 7. If newLen != numberLen, throw a RangeError exception.
3212 if (Object::NumberValue(*uint32_v) != Object::NumberValue(*number_v)) {
3213 DirectHandle<Object> exception =
3214 isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
3215 isolate->Throw(*exception);
3216 return false;
3217 }
3218 CHECK(Object::ToArrayLength(*uint32_v, output));
3219 return true;
3220}
3221
3222// ES6 9.4.2.4
3223// static
3225 PropertyDescriptor* desc,
3226 Maybe<ShouldThrow> should_throw) {
3227 // 1. If the [[Value]] field of Desc is absent, then
3228 if (!desc->has_value()) {
3229 // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
3230 return OrdinaryDefineOwnProperty(
3231 isolate, a, isolate->factory()->length_string(), desc, should_throw);
3232 }
3233 // 2. Let newLenDesc be a copy of Desc.
3234 // (Actual copying is not necessary.)
3235 PropertyDescriptor* new_len_desc = desc;
3236 // 3. - 7. Convert Desc.[[Value]] to newLen.
3237 uint32_t new_len = 0;
3238 if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) {
3239 DCHECK(isolate->has_exception());
3240 return Nothing<bool>();
3241 }
3242 // 8. Set newLenDesc.[[Value]] to newLen.
3243 // (Done below, if needed.)
3244 // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
3245 PropertyDescriptor old_len_desc;
3246 Maybe<bool> success = GetOwnPropertyDescriptor(
3247 isolate, a, isolate->factory()->length_string(), &old_len_desc);
3248 // 10. (Assert)
3249 DCHECK(success.FromJust());
3250 USE(success);
3251 // 11. Let oldLen be oldLenDesc.[[Value]].
3252 uint32_t old_len = 0;
3253 CHECK(Object::ToArrayLength(*old_len_desc.value(), &old_len));
3254 // 12. If newLen >= oldLen, then
3255 if (new_len >= old_len) {
3256 // 8. Set newLenDesc.[[Value]] to newLen.
3257 // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
3258 new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len));
3259 return OrdinaryDefineOwnProperty(isolate, a,
3260 isolate->factory()->length_string(),
3261 new_len_desc, should_throw);
3262 }
3263 // 13. If oldLenDesc.[[Writable]] is false, return false.
3264 if (!old_len_desc.writable() ||
3265 // Also handle the {configurable: true} and enumerable changes
3266 // since we later use JSArray::SetLength instead of
3267 // OrdinaryDefineOwnProperty to change the length,
3268 // and it doesn't have access to the descriptor anymore.
3269 new_len_desc->configurable() ||
3270 (new_len_desc->has_enumerable() &&
3271 (old_len_desc.enumerable() != new_len_desc->enumerable()))) {
3272 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
3273 NewTypeError(MessageTemplate::kRedefineDisallowed,
3274 isolate->factory()->length_string()));
3275 }
3276 // 14. If newLenDesc.[[Writable]] is absent or has the value true,
3277 // let newWritable be true.
3278 bool new_writable = false;
3279 if (!new_len_desc->has_writable() || new_len_desc->writable()) {
3280 new_writable = true;
3281 } else {
3282 // 15. Else,
3283 // 15a. Need to defer setting the [[Writable]] attribute to false in case
3284 // any elements cannot be deleted.
3285 // 15b. Let newWritable be false. (It's initialized as "false" anyway.)
3286 // 15c. Set newLenDesc.[[Writable]] to true.
3287 // (Not needed.)
3288 }
3289 // Most of steps 16 through 19 is implemented by JSArray::SetLength.
3291 // Steps 19d-ii, 20.
3292 if (!new_writable) {
3293 PropertyDescriptor readonly;
3294 readonly.set_writable(false);
3295 success = OrdinaryDefineOwnProperty(isolate, a,
3296 isolate->factory()->length_string(),
3297 &readonly, should_throw);
3298 DCHECK(success.FromJust());
3299 USE(success);
3300 }
3301 uint32_t actual_new_len = 0;
3302 CHECK(Object::ToArrayLength(a->length(), &actual_new_len));
3303 // Steps 19d-v, 21. Return false if there were non-deletable elements.
3304 bool result = actual_new_len == new_len;
3305 if (!result) {
3307 isolate, GetShouldThrow(isolate, should_throw),
3308 NewTypeError(MessageTemplate::kStrictDeleteProperty,
3309 isolate->factory()->NewNumberFromUint(actual_new_len - 1),
3310 a));
3311 }
3312 return Just(result);
3313}
3314
3315// ES6 9.5.6
3316// static
3320 PropertyDescriptor* desc,
3321 Maybe<ShouldThrow> should_throw) {
3322 STACK_CHECK(isolate, Nothing<bool>());
3323 if (IsSymbol(*key) && Cast<Symbol>(key)->IsPrivate()) {
3324 DCHECK(!Cast<Symbol>(key)->IsPrivateName());
3325 return JSProxy::SetPrivateSymbol(isolate, proxy, Cast<Symbol>(key), desc,
3326 should_throw);
3327 }
3328 DirectHandle<String> trap_name = isolate->factory()->defineProperty_string();
3329 // 1. Assert: IsPropertyKey(P) is true.
3330 DCHECK(IsName(*key) || IsNumber(*key));
3331 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
3332 DirectHandle<Object> handler(proxy->handler(), isolate);
3333 // 3. If handler is null, throw a TypeError exception.
3334 // 4. Assert: Type(handler) is Object.
3335 if (proxy->IsRevoked()) {
3336 isolate->Throw(*isolate->factory()->NewTypeError(
3337 MessageTemplate::kProxyRevoked, trap_name));
3338 return Nothing<bool>();
3339 }
3340 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
3341 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
3342 // 6. Let trap be ? GetMethod(handler, "defineProperty").
3345 isolate, trap,
3346 Object::GetMethod(isolate, Cast<JSReceiver>(handler), trap_name),
3347 Nothing<bool>());
3348 // 7. If trap is undefined, then:
3349 if (IsUndefined(*trap, isolate)) {
3350 // 7a. Return target.[[DefineOwnProperty]](P, Desc).
3351 return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
3352 should_throw);
3353 }
3354 // 8. Let descObj be FromPropertyDescriptor(Desc).
3355 DirectHandle<Object> desc_obj = desc->ToObject(isolate);
3356 // 9. Let booleanTrapResult be
3357 // ToBoolean(? Call(trap, handler, «target, P, descObj»)).
3358 DirectHandle<Name> property_name =
3359 IsName(*key) ? Cast<Name>(key)
3360 : Cast<Name>(isolate->factory()->NumberToString(key));
3361 // Do not leak private property names.
3362 DCHECK(!property_name->IsPrivate());
3363 DirectHandle<Object> trap_result_obj;
3364 DirectHandle<Object> args[] = {target, property_name, desc_obj};
3366 isolate, trap_result_obj,
3367 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
3368 Nothing<bool>());
3369 // 10. If booleanTrapResult is false, return false.
3370 if (!Object::BooleanValue(*trap_result_obj, isolate)) {
3371 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
3372 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor,
3373 trap_name, property_name));
3374 }
3375 // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
3376 PropertyDescriptor target_desc;
3377 Maybe<bool> target_found =
3378 JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
3379 MAYBE_RETURN(target_found, Nothing<bool>());
3380 // 12. Let extensibleTarget be ? IsExtensible(target).
3381 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(isolate, target);
3382 MAYBE_RETURN(maybe_extensible, Nothing<bool>());
3383 bool extensible_target = maybe_extensible.FromJust();
3384 // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
3385 // is false, then:
3386 // 13a. Let settingConfigFalse be true.
3387 // 14. Else let settingConfigFalse be false.
3388 bool setting_config_false = desc->has_configurable() && !desc->configurable();
3389 // 15. If targetDesc is undefined, then
3390 if (!target_found.FromJust()) {
3391 // 15a. If extensibleTarget is false, throw a TypeError exception.
3392 if (!extensible_target) {
3393 isolate->Throw(*isolate->factory()->NewTypeError(
3394 MessageTemplate::kProxyDefinePropertyNonExtensible, property_name));
3395 return Nothing<bool>();
3396 }
3397 // 15b. If settingConfigFalse is true, throw a TypeError exception.
3398 if (setting_config_false) {
3399 isolate->Throw(*isolate->factory()->NewTypeError(
3400 MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
3401 return Nothing<bool>();
3402 }
3403 } else {
3404 // 16. Else targetDesc is not undefined,
3405 // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
3406 // targetDesc) is false, throw a TypeError exception.
3407 Maybe<bool> valid = IsCompatiblePropertyDescriptor(
3408 isolate, extensible_target, desc, &target_desc, property_name,
3409 Just(kDontThrow));
3410 MAYBE_RETURN(valid, Nothing<bool>());
3411 if (!valid.FromJust()) {
3412 isolate->Throw(*isolate->factory()->NewTypeError(
3413 MessageTemplate::kProxyDefinePropertyIncompatible, property_name));
3414 return Nothing<bool>();
3415 }
3416 // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
3417 // true, throw a TypeError exception.
3418 if (setting_config_false && target_desc.configurable()) {
3419 isolate->Throw(*isolate->factory()->NewTypeError(
3420 MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name));
3421 return Nothing<bool>();
3422 }
3423 // 16c. If IsDataDescriptor(targetDesc) is true,
3424 // targetDesc.[[Configurable]] is
3425 // false, and targetDesc.[[Writable]] is true, then
3426 if (PropertyDescriptor::IsDataDescriptor(&target_desc) &&
3427 !target_desc.configurable() && target_desc.writable()) {
3428 // 16c i. If Desc has a [[Writable]] field and Desc.[[Writable]] is false,
3429 // throw a TypeError exception.
3430 if (desc->has_writable() && !desc->writable()) {
3431 isolate->Throw(*isolate->factory()->NewTypeError(
3432 MessageTemplate::kProxyDefinePropertyNonConfigurableWritable,
3433 property_name));
3434 return Nothing<bool>();
3435 }
3436 }
3437 }
3438 // 17. Return true.
3439 return Just(true);
3440}
3441
3442// static
3445 DirectHandle<Symbol> private_name,
3446 PropertyDescriptor* desc,
3447 Maybe<ShouldThrow> should_throw) {
3448 // Despite the generic name, this can only add private data properties.
3450 desc->ToAttributes() != DONT_ENUM) {
3451 RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
3452 NewTypeError(MessageTemplate::kProxyPrivate));
3453 }
3454 DCHECK(proxy->map()->is_dictionary_map());
3455 DirectHandle<Object> value =
3456 desc->has_value() ? desc->value()
3457 : Cast<Object>(isolate->factory()->undefined_value());
3458
3459 LookupIterator it(isolate, proxy, private_name, proxy);
3460
3461 if (it.IsFound()) {
3462 DCHECK_EQ(LookupIterator::DATA, it.state());
3463 DCHECK_EQ(DONT_ENUM, it.property_attributes());
3464 // We are not tracking constness for private symbols added to JSProxy
3465 // objects.
3466 DCHECK_EQ(PropertyConstness::kMutable, it.property_details().constness());
3467 it.WriteDataValue(value, false);
3468 return Just(true);
3469 }
3470
3474 DirectHandle<SwissNameDictionary> dict(proxy->property_dictionary_swiss(),
3475 isolate);
3477 SwissNameDictionary::Add(isolate, dict, private_name, value, details);
3478 if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
3479 } else {
3480 DirectHandle<NameDictionary> dict(proxy->property_dictionary(), isolate);
3482 NameDictionary::Add(isolate, dict, private_name, value, details);
3483 if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
3484 }
3485 return Just(true);
3486}
3487
3488// ES6 9.5.5
3489// static
3492 DirectHandle<Name> name,
3493 PropertyDescriptor* desc) {
3494 DCHECK(!name->IsPrivate());
3495 STACK_CHECK(isolate, Nothing<bool>());
3496
3497 DirectHandle<String> trap_name =
3498 isolate->factory()->getOwnPropertyDescriptor_string();
3499 // 1. (Assert)
3500 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
3501 DirectHandle<Object> handler(proxy->handler(), isolate);
3502 // 3. If handler is null, throw a TypeError exception.
3503 // 4. Assert: Type(handler) is Object.
3504 if (proxy->IsRevoked()) {
3505 isolate->Throw(*isolate->factory()->NewTypeError(
3506 MessageTemplate::kProxyRevoked, trap_name));
3507 return Nothing<bool>();
3508 }
3509 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
3510 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
3511 // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
3514 isolate, trap,
3515 Object::GetMethod(isolate, Cast<JSReceiver>(handler), trap_name),
3516 Nothing<bool>());
3517 // 7. If trap is undefined, then
3518 if (IsUndefined(*trap, isolate)) {
3519 // 7a. Return target.[[GetOwnProperty]](P).
3520 return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc);
3521 }
3522 // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
3523 Handle<JSAny> trap_result_obj;
3524 DirectHandle<Object> args[] = {target, name};
3526 isolate, trap_result_obj,
3528 Execution::Call(isolate, trap, handler, base::VectorOf(args))),
3529 Nothing<bool>());
3530 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
3531 // TypeError exception.
3532 if (!IsJSReceiver(*trap_result_obj) &&
3533 !IsUndefined(*trap_result_obj, isolate)) {
3534 isolate->Throw(*isolate->factory()->NewTypeError(
3535 MessageTemplate::kProxyGetOwnPropertyDescriptorInvalid, name));
3536 return Nothing<bool>();
3537 }
3538 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
3539 PropertyDescriptor target_desc;
3540 Maybe<bool> found =
3541 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
3542 MAYBE_RETURN(found, Nothing<bool>());
3543 // 11. If trapResultObj is undefined, then
3544 if (IsUndefined(*trap_result_obj, isolate)) {
3545 // 11a. If targetDesc is undefined, return undefined.
3546 if (!found.FromJust()) return Just(false);
3547 // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
3548 // exception.
3549 if (!target_desc.configurable()) {
3550 isolate->Throw(*isolate->factory()->NewTypeError(
3551 MessageTemplate::kProxyGetOwnPropertyDescriptorUndefined, name));
3552 return Nothing<bool>();
3553 }
3554 // 11c. Let extensibleTarget be ? IsExtensible(target).
3555 Maybe<bool> extensible_target = JSReceiver::IsExtensible(isolate, target);
3556 MAYBE_RETURN(extensible_target, Nothing<bool>());
3557 // 11d. (Assert)
3558 // 11e. If extensibleTarget is false, throw a TypeError exception.
3559 if (!extensible_target.FromJust()) {
3560 isolate->Throw(*isolate->factory()->NewTypeError(
3561 MessageTemplate::kProxyGetOwnPropertyDescriptorNonExtensible, name));
3562 return Nothing<bool>();
3563 }
3564 // 11f. Return undefined.
3565 return Just(false);
3566 }
3567 // 12. Let extensibleTarget be ? IsExtensible(target).
3568 Maybe<bool> extensible_target = JSReceiver::IsExtensible(isolate, target);
3569 MAYBE_RETURN(extensible_target, Nothing<bool>());
3570 // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
3571 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
3572 desc)) {
3573 DCHECK(isolate->has_exception());
3574 return Nothing<bool>();
3575 }
3576 // 14. Call CompletePropertyDescriptor(resultDesc).
3578 // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
3579 // resultDesc, targetDesc).
3580 Maybe<bool> valid = IsCompatiblePropertyDescriptor(
3581 isolate, extensible_target.FromJust(), desc, &target_desc, name,
3582 Just(kDontThrow));
3583 MAYBE_RETURN(valid, Nothing<bool>());
3584 // 16. If valid is false, throw a TypeError exception.
3585 if (!valid.FromJust()) {
3586 isolate->Throw(*isolate->factory()->NewTypeError(
3587 MessageTemplate::kProxyGetOwnPropertyDescriptorIncompatible, name));
3588 return Nothing<bool>();
3589 }
3590 // 17. If resultDesc.[[Configurable]] is false, then
3591 if (!desc->configurable()) {
3592 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
3593 if (target_desc.is_empty() || target_desc.configurable()) {
3594 // 17a i. Throw a TypeError exception.
3595 isolate->Throw(*isolate->factory()->NewTypeError(
3596 MessageTemplate::kProxyGetOwnPropertyDescriptorNonConfigurable,
3597 name));
3598 return Nothing<bool>();
3599 }
3600 // 17b. If resultDesc has a [[Writable]] field and resultDesc.[[Writable]]
3601 // is false, then
3602 if (desc->has_writable() && !desc->writable()) {
3603 // 17b i. If targetDesc.[[Writable]] is true, throw a TypeError exception.
3604 if (target_desc.writable()) {
3605 isolate->Throw(*isolate->factory()->NewTypeError(
3607 kProxyGetOwnPropertyDescriptorNonConfigurableWritable,
3608 name));
3609 return Nothing<bool>();
3610 }
3611 }
3612 }
3613 // 18. Return resultDesc.
3614 return Just(true);
3615}
3616
3618 ShouldThrow should_throw) {
3619 Isolate* isolate = proxy->GetIsolate();
3620 STACK_CHECK(isolate, Nothing<bool>());
3621 Factory* factory = isolate->factory();
3622 DirectHandle<String> trap_name = factory->preventExtensions_string();
3623
3624 if (proxy->IsRevoked()) {
3625 isolate->Throw(
3626 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
3627 return Nothing<bool>();
3628 }
3629 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
3630 DirectHandle<JSReceiver> handler(Cast<JSReceiver>(proxy->handler()), isolate);
3631
3634 isolate, trap, Object::GetMethod(isolate, handler, trap_name),
3635 Nothing<bool>());
3636 if (IsUndefined(*trap, isolate)) {
3637 return JSReceiver::PreventExtensions(isolate, target, should_throw);
3638 }
3639
3640 DirectHandle<Object> trap_result;
3641 DirectHandle<Object> args[] = {target};
3643 isolate, trap_result,
3644 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
3645 Nothing<bool>());
3646 if (!Object::BooleanValue(*trap_result, isolate)) {
3648 isolate, should_throw,
3649 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
3650 }
3651
3652 // Enforce the invariant.
3653 Maybe<bool> target_result = JSReceiver::IsExtensible(isolate, target);
3654 MAYBE_RETURN(target_result, Nothing<bool>());
3655 if (target_result.FromJust()) {
3656 isolate->Throw(*factory->NewTypeError(
3657 MessageTemplate::kProxyPreventExtensionsExtensible));
3658 return Nothing<bool>();
3659 }
3660 return Just(true);
3661}
3662
3664 Isolate* isolate = proxy->GetIsolate();
3665 STACK_CHECK(isolate, Nothing<bool>());
3666 Factory* factory = isolate->factory();
3667 DirectHandle<String> trap_name = factory->isExtensible_string();
3668
3669 if (proxy->IsRevoked()) {
3670 isolate->Throw(
3671 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
3672 return Nothing<bool>();
3673 }
3674 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
3675 DirectHandle<JSReceiver> handler(Cast<JSReceiver>(proxy->handler()), isolate);
3676
3679 isolate, trap, Object::GetMethod(isolate, handler, trap_name),
3680 Nothing<bool>());
3681 if (IsUndefined(*trap, isolate)) {
3682 return JSReceiver::IsExtensible(isolate, target);
3683 }
3684
3685 DirectHandle<Object> trap_result;
3686 DirectHandle<Object> args[] = {target};
3688 isolate, trap_result,
3689 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
3690 Nothing<bool>());
3691
3692 // Enforce the invariant.
3693 Maybe<bool> target_result = JSReceiver::IsExtensible(isolate, target);
3694 MAYBE_RETURN(target_result, Nothing<bool>());
3695 if (target_result.FromJust() != Object::BooleanValue(*trap_result, isolate)) {
3696 isolate->Throw(
3697 *factory->NewTypeError(MessageTemplate::kProxyIsExtensibleInconsistent,
3698 factory->ToBoolean(target_result.FromJust())));
3699 return Nothing<bool>();
3700 }
3701 return target_result;
3702}
3703
3705 Isolate* isolate, DirectHandle<DescriptorArray> desc, int enumeration_index,
3706 int slack) {
3707 return DescriptorArray::CopyUpToAddAttributes(isolate, desc,
3708 enumeration_index, NONE, slack);
3709}
3710
3712 Isolate* isolate, DirectHandle<DescriptorArray> source_handle,
3713 int enumeration_index, PropertyAttributes attributes, int slack) {
3714 if (enumeration_index + slack == 0) {
3715 return isolate->factory()->empty_descriptor_array();
3716 }
3717
3718 int size = enumeration_index;
3719 DirectHandle<DescriptorArray> copy_handle =
3720 DescriptorArray::Allocate(isolate, size, slack);
3721
3723 Tagged<DescriptorArray> source = *source_handle;
3724 Tagged<DescriptorArray> copy = *copy_handle;
3725
3726 if (attributes != NONE) {
3727 for (InternalIndex i : InternalIndex::Range(size)) {
3728 Tagged<MaybeObject> value_or_field_type = source->GetValue(i);
3729 Tagged<Name> key = source->GetKey(i);
3730 PropertyDetails details = source->GetDetails(i);
3731 // Bulk attribute changes never affect private properties.
3732 if (!key->IsPrivate()) {
3733 int mask = DONT_DELETE | DONT_ENUM;
3734 // READ_ONLY is an invalid attribute for JS setters/getters.
3735 Tagged<HeapObject> heap_object;
3736 if (details.kind() != PropertyKind::kAccessor ||
3737 !(value_or_field_type.GetHeapObjectIfStrong(&heap_object) &&
3738 IsAccessorPair(heap_object))) {
3739 mask |= READ_ONLY;
3740 }
3741 details = details.CopyAddAttributes(
3742 static_cast<PropertyAttributes>(attributes & mask));
3743 }
3744 copy->Set(i, key, value_or_field_type, details);
3745 }
3746 } else {
3747 for (InternalIndex i : InternalIndex::Range(size)) {
3748 copy->CopyFrom(i, source);
3749 }
3750 }
3751
3752 if (source->number_of_descriptors() != enumeration_index) copy->Sort();
3753
3754 return copy_handle;
3755}
3756
3758 int nof_descriptors) {
3759 for (InternalIndex i : InternalIndex::Range(nof_descriptors)) {
3760 if (GetKey(i) != desc->GetKey(i) || GetValue(i) != desc->GetValue(i)) {
3761 return false;
3762 }
3763 PropertyDetails details = GetDetails(i);
3764 PropertyDetails other_details = desc->GetDetails(i);
3765 if (details.kind() != other_details.kind() ||
3766 details.location() != other_details.location() ||
3767 !details.representation().Equals(other_details.representation())) {
3768 return false;
3769 }
3770 }
3771 return true;
3772}
3773
3774// static
3777 DirectHandle<Map> value,
3778 int* assigned_index) {
3779 int length = array->length();
3780 if (length == 0) {
3781 // Uninitialized WeakArrayList; need to initialize empty_slot_index.
3782 array = WeakArrayList::EnsureSpace(isolate, array, kFirstIndex + 1);
3784 array->Set(kFirstIndex, MakeWeak(*value));
3785 array->set_length(kFirstIndex + 1);
3786 if (assigned_index != nullptr) *assigned_index = kFirstIndex;
3787 return array;
3788 }
3789
3790 // If the array has unfilled space at the end, use it.
3791 if (!array->IsFull()) {
3792 array->Set(length, MakeWeak(*value));
3793 array->set_length(length + 1);
3794 if (assigned_index != nullptr) *assigned_index = length;
3795 return array;
3796 }
3797
3798 // If there are empty slots, use one of them.
3799 int empty_slot = Smi::ToInt(empty_slot_index(*array));
3800
3801 if (empty_slot == kNoEmptySlotsMarker) {
3802 // GCs might have cleared some references, rescan the array for empty slots.
3804 empty_slot = Smi::ToInt(empty_slot_index(*array));
3805 }
3806
3807 if (empty_slot != kNoEmptySlotsMarker) {
3808 DCHECK_GE(empty_slot, kFirstIndex);
3809 CHECK_LT(empty_slot, array->length());
3810 int next_empty_slot = array->Get(empty_slot).ToSmi().value();
3811
3812 array->Set(empty_slot, MakeWeak(*value));
3813 if (assigned_index != nullptr) *assigned_index = empty_slot;
3814
3815 set_empty_slot_index(*array, next_empty_slot);
3816 return array;
3817 } else {
3818 DCHECK_EQ(empty_slot, kNoEmptySlotsMarker);
3819 }
3820
3821 // Array full and no empty slots. Grow the array.
3822 array = WeakArrayList::EnsureSpace(isolate, array, length + 1);
3823 array->Set(length, MakeWeak(*value));
3824 array->set_length(length + 1);
3825 if (assigned_index != nullptr) *assigned_index = length;
3826 return array;
3827}
3828
3829// static
3831 for (int i = kFirstIndex; i < array->length(); i++) {
3832 if (array->Get(i).IsCleared()) {
3834 }
3835 }
3836}
3837
3839 Heap* heap,
3841 AllocationType allocation) {
3842 if (array->length() == 0) {
3843 return *array;
3844 }
3845 int new_length = kFirstIndex + array->CountLiveWeakReferences();
3846 if (new_length == array->length()) {
3847 return *array;
3848 }
3849
3851 heap->isolate(),
3852 handle(ReadOnlyRoots(heap).empty_weak_array_list(), heap->isolate()),
3853 new_length, allocation);
3854 // Allocation might have caused GC and turned some of the elements into
3855 // cleared weak heap objects. Count the number of live objects again.
3856 int copy_to = kFirstIndex;
3857 for (int i = kFirstIndex; i < array->length(); i++) {
3858 Tagged<MaybeObject> element = array->Get(i);
3860 if (element.GetHeapObjectIfWeak(&value)) {
3861 callback(value, i, copy_to);
3862 new_array->Set(copy_to++, element);
3863 } else {
3864 DCHECK(element.IsCleared() || element.IsSmi());
3865 }
3866 }
3867 new_array->set_length(copy_to);
3869 return *new_array;
3870}
3871
3872template <typename IsolateT>
3874 int nof_descriptors,
3875 int slack,
3876 AllocationType allocation) {
3877 return nof_descriptors + slack == 0
3878 ? isolate->factory()->empty_descriptor_array()
3879 : isolate->factory()->NewDescriptorArray(nof_descriptors, slack,
3880 allocation);
3881}
3883 Isolate* isolate, int nof_descriptors, int slack,
3884 AllocationType allocation);
3886 LocalIsolate* isolate, int nof_descriptors, int slack,
3887 AllocationType allocation);
3888
3890 Tagged<HeapObject> undefined_value,
3891 int nof_descriptors, int slack,
3892 uint32_t raw_gc_state) {
3893 DCHECK_GE(nof_descriptors, 0);
3894 DCHECK_GE(slack, 0);
3895 DCHECK_LE(nof_descriptors + slack, kMaxNumberOfDescriptors);
3896 set_number_of_all_descriptors(nof_descriptors + slack);
3897 set_number_of_descriptors(nof_descriptors);
3898 set_raw_gc_state(raw_gc_state, kRelaxedStore);
3899 set_enum_cache(empty_enum_cache, SKIP_WRITE_BARRIER);
3900 MemsetTagged(GetDescriptorSlot(0), undefined_value,
3901 number_of_all_descriptors() * kEntrySize);
3902}
3903
3905 set_enum_cache(GetReadOnlyRoots().empty_enum_cache(), SKIP_WRITE_BARRIER);
3906}
3907
3909 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index.as_int()));
3910 Set(index, descriptor);
3911}
3912
3913// static
3915 DirectHandle<DescriptorArray> descriptors, Isolate* isolate,
3917 AllocationType allocation_if_initialize) {
3918 Tagged<EnumCache> enum_cache = descriptors->enum_cache();
3919 if (enum_cache == ReadOnlyRoots(isolate).empty_enum_cache()) {
3920 enum_cache = *isolate->factory()->NewEnumCache(keys, indices,
3921 allocation_if_initialize);
3922 descriptors->set_enum_cache(enum_cache);
3923 } else {
3924 enum_cache->set_keys(*keys);
3925 enum_cache->set_indices(*indices);
3926 }
3927}
3928
3931 PropertyDetails details = src->GetDetails(index);
3932 Set(index, src->GetKey(index), src->GetValue(index), details);
3933}
3934
3936 // In-place heap sort.
3937 const int len = number_of_descriptors();
3938 // Reset sorting since the descriptor array might contain invalid pointers.
3939 for (int i = 0; i < len; ++i) SetSortedKey(i, i);
3940 // Bottom-up max-heap construction.
3941 // Index of the last node with children.
3942 int max_parent_index = (len / 2) - 1;
3943 for (int i = max_parent_index; i >= 0; --i) {
3944 int parent_index = i;
3945 const uint32_t parent_hash = GetSortedKey(i)->hash();
3946 while (parent_index <= max_parent_index) {
3947 int child_index = 2 * parent_index + 1;
3948 uint32_t child_hash = GetSortedKey(child_index)->hash();
3949 if (child_index + 1 < len) {
3950 uint32_t right_child_hash = GetSortedKey(child_index + 1)->hash();
3951 if (right_child_hash > child_hash) {
3952 child_index++;
3953 child_hash = right_child_hash;
3954 }
3955 }
3956 if (child_hash <= parent_hash) break;
3957 SwapSortedKeys(parent_index, child_index);
3958 // Now element at child_index could be < its children.
3959 parent_index = child_index; // parent_hash remains correct.
3960 }
3961 }
3962
3963 // Extract elements and create sorted array.
3964 for (int i = len - 1; i > 0; --i) {
3965 // Put max element at the back of the array.
3966 SwapSortedKeys(0, i);
3967 // Shift down the new top element.
3968 int parent_index = 0;
3969 const uint32_t parent_hash = GetSortedKey(parent_index)->hash();
3970 max_parent_index = (i / 2) - 1;
3971 while (parent_index <= max_parent_index) {
3972 int child_index = parent_index * 2 + 1;
3973 uint32_t child_hash = GetSortedKey(child_index)->hash();
3974 if (child_index + 1 < i) {
3975 uint32_t right_child_hash = GetSortedKey(child_index + 1)->hash();
3976 if (right_child_hash > child_hash) {
3977 child_index++;
3978 child_hash = right_child_hash;
3979 }
3980 }
3981 if (child_hash <= parent_hash) break;
3982 SwapSortedKeys(parent_index, child_index);
3983 parent_index = child_index;
3984 }
3985 }
3986 DCHECK(IsSortedNoDuplicates());
3987}
3988
3990 uint32_t desc_hash,
3991 int insertion_index) {
3992 DCHECK_GE(insertion_index, 0);
3993 DCHECK_LE(insertion_index, number_of_all_descriptors());
3994
3995 if (insertion_index <= 0) return;
3996
3997 for (int i = insertion_index; i > 0; --i) {
3998 Tagged<Name> current_key = GetSortedKey(i - 1);
3999 if (current_key->hash() != desc_hash) return;
4000 CHECK(current_key != *desc->GetKey());
4001 }
4002}
4003
4006 DirectHandle<AccessorPair> copy = isolate->factory()->NewAccessorPair();
4008 Tagged<AccessorPair> raw_src = *pair;
4009 Tagged<AccessorPair> raw_copy = *copy;
4010 raw_copy->set_getter(raw_src->getter());
4011 raw_copy->set_setter(raw_src->setter());
4012 return copy;
4013}
4014
4017 DirectHandle<AccessorPair> accessor_pair, AccessorComponent component) {
4018 Handle<Object> accessor(accessor_pair->get(component), isolate);
4019 if (IsFunctionTemplateInfo(*accessor)) {
4020 // TODO(v8:5962): pass the right name here: "get "/"set " + prop.
4021 Handle<JSFunction> function =
4024 .ToHandleChecked();
4025 accessor_pair->set(component, *function, kReleaseStore);
4026 return function;
4027 }
4028 if (IsNull(*accessor, isolate)) {
4029 return isolate->factory()->undefined_value();
4030 }
4031 return Cast<JSAny>(accessor);
4032}
4033
4034#ifdef DEBUG
4035bool DescriptorArray::IsEqualTo(Tagged<DescriptorArray> other) {
4036 if (number_of_all_descriptors() != other->number_of_all_descriptors()) {
4037 return false;
4038 }
4039 for (InternalIndex i : InternalIndex::Range(number_of_descriptors())) {
4040 if (GetKey(i) != other->GetKey(i)) return false;
4041 if (GetDetails(i).AsSmi() != other->GetDetails(i).AsSmi()) return false;
4042 if (GetValue(i) != other->GetValue(i)) return false;
4043 }
4044 return true;
4045}
4046#endif
4047
4048// static
4050 DirectHandle<Name> name) {
4051 if (IsString(*name)) return Cast<String>(name);
4052 // ES6 section 9.2.11 SetFunctionName, step 4.
4053 DirectHandle<Object> description(Cast<Symbol>(name)->description(), isolate);
4054 if (IsUndefined(*description, isolate)) {
4055 return isolate->factory()->empty_string();
4056 }
4057 IncrementalStringBuilder builder(isolate);
4058 builder.AppendCharacter('[');
4059 builder.AppendString(Cast<String>(description));
4060 builder.AppendCharacter(']');
4061 return builder.Finish();
4062}
4063
4064// static
4066 DirectHandle<Name> name,
4067 DirectHandle<String> prefix) {
4068 DirectHandle<String> name_string;
4069 ASSIGN_RETURN_ON_EXCEPTION(isolate, name_string,
4070 ToFunctionName(isolate, name));
4071 IncrementalStringBuilder builder(isolate);
4072 builder.AppendString(prefix);
4073 builder.AppendCharacter(' ');
4074 builder.AppendString(name_string);
4075 return builder.Finish();
4076}
4077
4079 Relocatable* current = isolate->relocatable_top();
4080 while (current != nullptr) {
4081 current->PostGarbageCollection();
4082 current = current->prev_;
4083 }
4084}
4085
4086// Reserve space for statics needing saving and restoring.
4088
4089// Archive statics that are thread-local.
4090char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
4091 *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
4092 isolate->set_relocatable_top(nullptr);
4093 return to + ArchiveSpacePerThread();
4094}
4095
4096// Restore statics that are thread-local.
4097char* Relocatable::RestoreState(Isolate* isolate, char* from) {
4098 isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
4099 return from + ArchiveSpacePerThread();
4100}
4101
4102char* Relocatable::Iterate(RootVisitor* v, char* thread_storage) {
4103 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
4104 Iterate(v, top);
4105 return thread_storage + ArchiveSpacePerThread();
4106}
4107
4109 Iterate(v, isolate->relocatable_top());
4110}
4111
4113 Relocatable* current = top;
4114 while (current != nullptr) {
4115 current->IterateInstance(v);
4116 current = current->prev_;
4117 }
4118}
4119
4120namespace {
4121
4122template <typename sinkchar>
4123void WriteFixedArrayToFlat(Tagged<FixedArray> fixed_array, int length,
4124 Tagged<String> separator, sinkchar* sink,
4125 int sink_length) {
4127 CHECK_GT(length, 0);
4128 CHECK_LE(length, fixed_array->length());
4129#ifdef DEBUG
4130 sinkchar* sink_end = sink + sink_length;
4131#endif
4132
4133 const int separator_length = separator->length();
4134 const bool use_one_byte_separator_fast_path =
4135 separator_length == 1 && sizeof(sinkchar) == 1 &&
4137 uint8_t separator_one_char;
4138 if (use_one_byte_separator_fast_path) {
4139 CHECK(StringShape(separator).IsSequentialOneByte());
4140 CHECK_EQ(separator->length(), 1);
4141 separator_one_char = Cast<SeqOneByteString>(separator)->GetChars(no_gc)[0];
4142 }
4143
4144 uint32_t num_separators = 0;
4145 uint32_t repeat_last = 0;
4146 for (int i = 0; i < length; i++) {
4147 Tagged<Object> element = fixed_array->get(i);
4148 const bool element_is_special = IsSmi(element);
4149
4150 // If element is a positive Smi, it represents the number of separators to
4151 // write. If it is a negative Smi, it represents the number of times the
4152 // last string is repeated.
4153 if (V8_UNLIKELY(element_is_special)) {
4154 int count;
4155 CHECK(Object::ToInt32(element, &count));
4156 if (count > 0) {
4157 num_separators = count;
4158 // Verify that Smis (number of separators) only occur when necessary:
4159 // 1) at the beginning
4160 // 2) at the end
4161 // 3) when the number of separators > 1
4162 // - It is assumed that consecutive Strings will have one
4163 // separator,
4164 // so there is no need for a Smi.
4165 DCHECK(i == 0 || i == length - 1 || num_separators > 1);
4166 } else {
4167 repeat_last = -count;
4168 // Repeat is only possible when the previous element is not special.
4169 DCHECK_GT(i, 0);
4170 DCHECK(IsString(fixed_array->get(i - 1)));
4171 }
4172 }
4173
4174 // Write separator(s) if necessary.
4175 if (num_separators > 0 && separator_length > 0) {
4176 // TODO(pwong): Consider doubling strategy employed by runtime-strings.cc
4177 // WriteRepeatToFlat().
4178 // Fast path for single character, single byte separators.
4179 if (use_one_byte_separator_fast_path) {
4180 DCHECK_LE(sink + num_separators, sink_end);
4181 memset(sink, separator_one_char, num_separators);
4182 DCHECK_EQ(separator_length, 1);
4183 sink += num_separators;
4184 } else {
4185 for (uint32_t j = 0; j < num_separators; j++) {
4186 DCHECK_LE(sink + separator_length, sink_end);
4187 String::WriteToFlat(separator, sink, 0, separator_length);
4188 sink += separator_length;
4189 }
4190 }
4191 num_separators = 0;
4192 }
4193
4194 // Repeat the last written string |repeat_last| times (including
4195 // separators).
4196 if (V8_UNLIKELY(repeat_last > 0)) {
4197 Tagged<Object> last_element = fixed_array->get(i - 1);
4198 int string_length = Cast<String>(last_element)->length();
4199 // The implemented logic requires that string length is > 0. Empty strings
4200 // are handled by repeating the separator (positive smi in the fixed
4201 // array) already.
4202 DCHECK_GT(string_length, 0);
4203 int length_with_sep = string_length + separator_length;
4204 // Only copy separators between elements, not at the start or beginning.
4205 sinkchar* copy_end =
4206 sink + (length_with_sep * repeat_last) - separator_length;
4207 int copy_length = length_with_sep;
4208 while (sink < copy_end - copy_length) {
4209 DCHECK_LE(sink + copy_length, sink_end);
4210 memcpy(sink, sink - copy_length, copy_length * sizeof(sinkchar));
4211 sink += copy_length;
4212 copy_length *= 2;
4213 }
4214 int remaining = static_cast<int>(copy_end - sink);
4215 if (remaining > 0) {
4216 DCHECK_LE(sink + remaining, sink_end);
4217 memcpy(sink, sink - remaining - separator_length,
4218 remaining * sizeof(sinkchar));
4219 sink += remaining;
4220 }
4221 repeat_last = 0;
4222 num_separators = 1;
4223 }
4224
4225 if (V8_LIKELY(!element_is_special)) {
4226 DCHECK(IsString(element));
4227 Tagged<String> string = Cast<String>(element);
4228 const int string_length = string->length();
4229
4230 DCHECK(string_length == 0 || sink < sink_end);
4231 String::WriteToFlat(string, sink, 0, string_length);
4232 sink += string_length;
4233
4234 // Next string element, needs at least one separator preceding it.
4235 num_separators = 1;
4236 }
4237 }
4238
4239 // Verify we have written to the end of the sink.
4240 DCHECK_EQ(sink, sink_end);
4241}
4242
4243} // namespace
4244
4245// static
4247 Address raw_fixed_array,
4248 intptr_t length,
4249 Address raw_separator,
4250 Address raw_dest) {
4252 DisallowJavascriptExecution no_js(isolate);
4253 Tagged<FixedArray> fixed_array =
4254 Cast<FixedArray>(Tagged<Object>(raw_fixed_array));
4256 Tagged<String> dest = Cast<String>(Tagged<Object>(raw_dest));
4257 DCHECK(IsFixedArray(fixed_array));
4258 DCHECK(StringShape(dest).IsSequentialOneByte() ||
4259 StringShape(dest).IsSequentialTwoByte());
4260
4261 if (StringShape(dest).IsSequentialOneByte()) {
4262 WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
4263 Cast<SeqOneByteString>(dest)->GetChars(no_gc),
4264 dest->length());
4265 } else {
4266 DCHECK(StringShape(dest).IsSequentialTwoByte());
4267 WriteFixedArrayToFlat(fixed_array, static_cast<int>(length), separator,
4268 Cast<SeqTwoByteString>(dest)->GetChars(no_gc),
4269 dest->length());
4270 }
4271 return dest.ptr();
4272}
4273
4275 const char* to_string, DirectHandle<Number> to_number,
4276 const char* type_of, uint8_t kind) {
4277 DirectHandle<String> internalized_to_string =
4278 isolate->factory()->InternalizeUtf8String(to_string);
4279 DirectHandle<String> internalized_type_of =
4280 isolate->factory()->InternalizeUtf8String(type_of);
4281 if (IsHeapNumber(*to_number)) {
4282 oddball->set_to_number_raw_as_bits(
4283 Cast<HeapNumber>(to_number)->value_as_bits());
4284 } else {
4285 oddball->set_to_number_raw(Object::NumberValue(*to_number));
4286 }
4287 oddball->set_to_number(*to_number);
4288 oddball->set_to_string(*internalized_to_string);
4289 oddball->set_type_of(*internalized_type_of);
4290 oddball->set_kind(kind);
4291}
4292
4293// static
4295 DCHECK(script->compilation_type() == Script::CompilationType::kEval);
4296 int position = script->eval_from_position();
4297 if (position < 0) {
4298 // Due to laziness, the position may not have been translated from code
4299 // offset yet, which would be encoded as negative integer. In that case,
4300 // translate and set the position.
4301 if (!script->has_eval_from_shared()) {
4302 position = 0;
4303 } else {
4304 DirectHandle<SharedFunctionInfo> shared(script->eval_from_shared(),
4305 isolate);
4307 position =
4308 shared->abstract_code(isolate)->SourcePosition(isolate, -position);
4309 }
4310 DCHECK_GE(position, 0);
4311 script->set_eval_from_position(position);
4312 }
4313 return position;
4314}
4315
4317 DirectHandle<Script> script) {
4318 DCHECK(!script->has_line_ends());
4319 Tagged<Object> src_obj = script->source();
4320 if (IsString(src_obj)) {
4321 DirectHandle<String> src(Cast<String>(src_obj), isolate);
4322 return String::CalculateLineEndsVector(isolate, src, true);
4323 }
4324
4325 return String::LineEndsVector();
4326}
4327
4328template <typename IsolateT>
4329// static
4330void Script::InitLineEndsInternal(IsolateT* isolate,
4331 DirectHandle<Script> script) {
4332 DCHECK(!script->has_line_ends());
4333 DCHECK(script->CanHaveLineEnds());
4334 Tagged<Object> src_obj = script->source();
4335 if (!IsString(src_obj)) {
4336 DCHECK(IsUndefined(src_obj, isolate));
4337 script->set_line_ends(ReadOnlyRoots(isolate).empty_fixed_array());
4338 } else {
4339 DCHECK(IsString(src_obj));
4340 DirectHandle<String> src(Cast<String>(src_obj), isolate);
4342 String::CalculateLineEnds(isolate, src, true);
4343 script->set_line_ends(*array);
4344 }
4345 DCHECK(IsFixedArray(script->line_ends()));
4346 DCHECK(script->has_line_ends());
4347}
4348
4350 DirectHandle<String> source) {
4351 script->set_source(*source);
4352 if (isolate->NeedsSourcePositions()) {
4353 InitLineEnds(isolate, script);
4354 } else if (script->line_ends() ==
4355 ReadOnlyRoots(isolate).empty_fixed_array()) {
4356 DCHECK(script->has_line_ends());
4357 script->set_line_ends(Smi::zero());
4358 DCHECK(!script->has_line_ends());
4359 }
4360}
4361
4363 Isolate* isolate, DirectHandle<Script> script);
4365 LocalIsolate* isolate, DirectHandle<Script> script);
4366
4368 PositionInfo* info, OffsetFlag offset_flag) {
4369#if V8_ENABLE_WEBASSEMBLY
4370 // For wasm, we do not create an artificial line_ends array, but do the
4371 // translation directly.
4372#ifdef DEBUG
4373 if (script->type() == Type::kWasm) {
4374 DCHECK(script->has_line_ends());
4375 DCHECK_EQ(Cast<FixedArray>(script->line_ends())->length(), 0);
4376 }
4377#endif // DEBUG
4378#endif // V8_ENABLE_WEBASSEMBLY
4379 InitLineEnds(script->GetIsolate(), script);
4380 return script->GetPositionInfo(position, info, offset_flag);
4381}
4382
4384 switch (type()) {
4385 case Type::kNormal:
4386#if V8_ENABLE_WEBASSEMBLY
4387 case Type::kWasm:
4388#endif // V8_ENABLE_WEBASSEMBLY
4389 return true;
4390 case Type::kNative:
4391 case Type::kInspector:
4392 case Type::kExtension:
4393 return false;
4394 }
4395 UNREACHABLE();
4396}
4397
4399 return type() == Script::Type::kNormal;
4400}
4401
4402#if V8_ENABLE_WEBASSEMBLY
4403bool Script::ContainsAsmModule() {
4405 SharedFunctionInfo::ScriptIterator iter(this->GetIsolate(), *this);
4406 for (Tagged<SharedFunctionInfo> sfi = iter.Next(); !sfi.is_null();
4407 sfi = iter.Next()) {
4408 if (sfi->HasAsmWasmData()) return true;
4409 }
4410 return false;
4411}
4412#endif // V8_ENABLE_WEBASSEMBLY
4413
4416 Isolate* isolate = this->GetIsolate();
4417 Tagged<Object> context_value = isolate->native_context()->debug_context_id();
4418 int contextId = (IsSmi(context_value)) ? Smi::ToInt(context_value) : 0;
4419 auto value = v8::tracing::TracedValue::Create();
4420 value->SetInteger("scriptId", this->id());
4421 value->SetInteger("executionContextId", contextId);
4422 value->SetUnsignedInteger("isolate", isolate->debug()->IsolateId());
4423 value->SetBoolean("isModule", this->origin_options().IsModule());
4424 value->SetBoolean("hasSourceUrl", this->HasSourceURLComment());
4425 if (this->HasValidSource()) {
4426 if (this->HasSourceURLComment()) {
4427 value->SetString("sourceUrl",
4428 Cast<String>(this->source_url())->ToCString().get());
4429 }
4430 if (this->HasSourceMappingURLComment()) {
4431 value->SetString(
4432 "sourceMapUrl",
4433 Cast<String>(this->source_mapping_url())->ToCString().get());
4434 }
4435 }
4436 if (IsString(this->name())) {
4437 value->SetString("url", Cast<String>(this->name())->ToCString().get());
4438 }
4439 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.v8-source-rundown"),
4440 "ScriptCatchup", "data", std::move(value));
4441}
4442
4445 Isolate* isolate = this->GetIsolate();
4446 if (!IsString(this->source())) return;
4447 Tagged<String> source = Cast<String>(this->source());
4448 auto script_id = this->id();
4449 int32_t source_length = source->length();
4450 const int32_t kSplitMaxLength = 1000000;
4451 if (source_length <= kSplitMaxLength) {
4452 auto value = v8::tracing::TracedValue::Create();
4453 value->SetUnsignedInteger("isolate", isolate->debug()->IsolateId());
4454 value->SetInteger("scriptId", script_id);
4455 value->SetInteger("length", source_length);
4456 value->SetString("sourceText", source->ToCString().get());
4458 TRACE_DISABLED_BY_DEFAULT("devtools.v8-source-rundown-sources"),
4459 "ScriptCatchup", "data", std::move(value));
4460 } else {
4461 int32_t split_count = source_length / kSplitMaxLength + 1;
4462 std::unique_ptr<char[]> source_ptr = source->ToCString();
4463 for (int32_t i = 0; i < split_count; i++) {
4464 int32_t begin = i * kSplitMaxLength;
4465 int32_t end = std::min(begin + kSplitMaxLength, source_length);
4466 auto split_trace_value = v8::tracing::TracedValue::Create();
4467 split_trace_value->SetInteger("splitIndex", i);
4468 split_trace_value->SetInteger("splitCount", split_count);
4469 split_trace_value->SetUnsignedInteger("isolate",
4470 isolate->debug()->IsolateId());
4471 split_trace_value->SetInteger("scriptId", script_id);
4472 split_trace_value->SetString(
4473 "sourceText", std::string(source_ptr.get() + begin, end - begin));
4475 TRACE_DISABLED_BY_DEFAULT("devtools.v8-source-rundown-sources"),
4476 "LargeScriptCatchup", "data", std::move(split_trace_value));
4477 }
4478 }
4479}
4480
4481namespace {
4482
4483template <typename Char>
4484bool GetPositionInfoSlowImpl(base::Vector<Char> source, int position,
4485 Script::PositionInfo* info) {
4486 DCHECK(DisallowPositionInfoSlow::IsAllowed());
4487 if (position < 0) {
4488 position = 0;
4489 }
4490 int line = 0;
4491 const auto begin = std::cbegin(source);
4492 const auto end = std::cend(source);
4493 for (auto line_begin = begin; line_begin < end;) {
4494 const auto line_end = std::find(line_begin, end, '\n');
4495 if (position <= (line_end - begin)) {
4496 info->line = line;
4497 info->column = static_cast<int>((begin + position) - line_begin);
4498 info->line_start = static_cast<int>(line_begin - begin);
4499 info->line_end = static_cast<int>(line_end - begin);
4500 return true;
4501 }
4502 ++line;
4503 line_begin = line_end + 1;
4504 }
4505 return false;
4506}
4507bool GetPositionInfoSlow(const Tagged<Script> script, int position,
4508 const DisallowGarbageCollection& no_gc,
4509 Script::PositionInfo* info) {
4510 if (!IsString(script->source())) {
4511 return false;
4512 }
4513 auto source = Cast<String>(script->source());
4514 const auto flat = source->GetFlatContent(no_gc);
4515 return flat.IsOneByte()
4516 ? GetPositionInfoSlowImpl(flat.ToOneByteVector(), position, info)
4517 : GetPositionInfoSlowImpl(flat.ToUC16Vector(), position, info);
4518}
4519
4520int GetLineEnd(const String::LineEndsVector& vector, int line) {
4521 return vector[line];
4522}
4523
4524int GetLineEnd(const Tagged<FixedArray>& array, int line) {
4525 return Smi::ToInt(array->get(line));
4526}
4527
4528int GetLength(const String::LineEndsVector& vector) {
4529 return static_cast<int>(vector.size());
4530}
4531
4532int GetLength(const Tagged<FixedArray>& array) { return array->length(); }
4533
4534template <typename LineEndsContainer>
4535bool GetLineEndsContainerPositionInfo(const LineEndsContainer& ends,
4536 int position, Script::PositionInfo* info,
4537 const DisallowGarbageCollection& no_gc) {
4538 const int ends_len = GetLength(ends);
4539 if (ends_len == 0) return false;
4540
4541 // Return early on invalid positions. Negative positions behave as if 0 was
4542 // passed, and positions beyond the end of the script return as failure.
4543 if (position < 0) {
4544 position = 0;
4545 } else if (position > GetLineEnd(ends, ends_len - 1)) {
4546 return false;
4547 }
4548
4549 // Determine line number by doing a binary search on the line ends array.
4550 if (GetLineEnd(ends, 0) >= position) {
4551 info->line = 0;
4552 info->line_start = 0;
4553 info->column = position;
4554 } else {
4555 int left = 0;
4556 int right = ends_len - 1;
4557
4558 while (right > 0) {
4559 DCHECK_LE(left, right);
4560 const int mid = left + (right - left) / 2;
4561 if (position > GetLineEnd(ends, mid)) {
4562 left = mid + 1;
4563 } else if (position <= GetLineEnd(ends, mid - 1)) {
4564 right = mid - 1;
4565 } else {
4566 info->line = mid;
4567 break;
4568 }
4569 }
4570 DCHECK(GetLineEnd(ends, info->line) >= position &&
4571 GetLineEnd(ends, info->line - 1) < position);
4572 info->line_start = GetLineEnd(ends, info->line - 1) + 1;
4573 info->column = position - info->line_start;
4574 }
4575
4576 return true;
4577}
4578
4579} // namespace
4580
4582 OffsetFlag offset_flag) const {
4583 // Add offsets if requested.
4584 if (offset_flag == OffsetFlag::kWithOffset) {
4585 if (info->line == 0) {
4586 info->column += column_offset();
4587 }
4588 info->line += line_offset();
4589 } else {
4590 DCHECK_EQ(offset_flag, OffsetFlag::kNoOffset);
4591 }
4592}
4593
4594template <typename LineEndsContainer>
4596 const LineEndsContainer& ends, int position, Script::PositionInfo* info,
4597 const DisallowGarbageCollection& no_gc) const {
4598 if (!GetLineEndsContainerPositionInfo(ends, position, info, no_gc))
4599 return false;
4600
4601 // Line end is position of the linebreak character.
4602 info->line_end = GetLineEnd(ends, info->line);
4603 if (info->line_end > 0) {
4604 DCHECK(IsString(source()));
4606 if (src->length() >= static_cast<uint32_t>(info->line_end) &&
4607 src->Get(info->line_end - 1) == '\r') {
4608 info->line_end--;
4609 }
4610 }
4611
4612 return true;
4613}
4614
4615template bool Script::GetPositionInfoInternal<String::LineEndsVector>(
4616 const String::LineEndsVector& ends, int position,
4617 Script::PositionInfo* info, const DisallowGarbageCollection& no_gc) const;
4620 const DisallowGarbageCollection& no_gc) const;
4621
4623 OffsetFlag offset_flag) const {
4625
4626#if V8_ENABLE_WEBASSEMBLY
4627 // For wasm, we use the byte offset as the column.
4628 if (type() == Script::Type::kWasm) {
4629 DCHECK_LE(0, position);
4630 wasm::NativeModule* native_module = wasm_native_module();
4631 const wasm::WasmModule* module = native_module->module();
4632 if (module->functions.empty()) return false;
4633 info->line = 0;
4634 info->column = position;
4635 info->line_start = module->functions[0].code.offset();
4636 info->line_end = module->functions.back().code.end_offset();
4637 return true;
4638 }
4639#endif // V8_ENABLE_WEBASSEMBLY
4640
4641 if (!has_line_ends()) {
4642 // Slow mode: we do not have line_ends. We have to iterate through source.
4643 if (!GetPositionInfoSlow(*this, position, no_gc, info)) {
4644 return false;
4645 }
4646 } else {
4648 Tagged<FixedArray> ends = Cast<FixedArray>(line_ends());
4649
4650 if (!GetPositionInfoInternal(ends, position, info, no_gc)) return false;
4651 }
4652
4653 AddPositionInfoOffset(info, offset_flag);
4654
4655 return true;
4656}
4657
4659 int position, PositionInfo* info, const String::LineEndsVector& line_ends,
4660 OffsetFlag offset_flag) const {
4662 if (!GetPositionInfoInternal(line_ends, position, info, no_gc)) return false;
4663
4664 AddPositionInfoOffset(info, offset_flag);
4665
4666 return true;
4667}
4668
4670 int position, int& line, int& column,
4671 const String::LineEndsVector& line_ends) {
4674 if (!GetLineEndsContainerPositionInfo(line_ends, position, &info, no_gc)) {
4675 line = -1;
4676 column = -1;
4677 return false;
4678 }
4679
4680 line = info.line;
4681 column = info.column;
4682
4683 return true;
4684}
4685
4688 GetPositionInfo(script, code_pos, &info);
4689 return info.column;
4690}
4691
4692int Script::GetColumnNumber(int code_pos) const {
4694 GetPositionInfo(code_pos, &info);
4695 return info.column;
4696}
4697
4700 GetPositionInfo(script, code_pos, &info);
4701 return info.line;
4702}
4703
4704int Script::GetLineNumber(int code_pos) const {
4706 GetPositionInfo(code_pos, &info);
4707 return info.line;
4708}
4709
4711 // Keep in sync with ScriptNameOrSourceURL in messages.js.
4712 if (!IsUndefined(source_url())) return source_url();
4713 return name();
4714}
4715
4716// static
4718 DirectHandle<Script> script,
4719 bool forceForInspector) {
4720 if (script->origin_options().IsOpaque() && !forceForInspector) {
4721 return isolate->factory()->empty_string();
4722 }
4723
4724 PtrComprCageBase cage_base(isolate);
4725 {
4726 Tagged<Object> maybe_source_hash = script->source_hash(cage_base);
4727 if (IsString(maybe_source_hash, cage_base)) {
4728 DirectHandle<String> precomputed(Cast<String>(maybe_source_hash),
4729 isolate);
4730 if (precomputed->length() > 0) {
4731 return precomputed;
4732 }
4733 }
4734 }
4735
4736 DirectHandle<String> src_text;
4737 {
4738 Tagged<Object> maybe_script_source = script->source(cage_base);
4739
4740 if (!IsString(maybe_script_source, cage_base)) {
4741 return isolate->factory()->empty_string();
4742 }
4743 src_text = direct_handle(Cast<String>(maybe_script_source), isolate);
4744 }
4745
4746 char formatted_hash[kSizeOfFormattedSha256Digest];
4747
4748 std::unique_ptr<char[]> string_val = src_text->ToCString();
4749 size_t len = strlen(string_val.get());
4750 uint8_t hash[kSizeOfSha256Digest];
4751 SHA256_hash(string_val.get(), len, hash);
4752 FormatBytesToHex(formatted_hash, kSizeOfFormattedSha256Digest, hash,
4754 formatted_hash[kSizeOfSha256Digest * 2] = '\0';
4755
4757 isolate->factory()->NewStringFromAsciiChecked(formatted_hash);
4758 script->set_source_hash(*result);
4759 return result;
4760}
4761
4762template <typename IsolateT>
4764 DirectHandle<Script> script, IsolateT* isolate,
4765 FunctionLiteral* function_literal) {
4766 DCHECK(function_literal->shared_function_info().is_null());
4767 int function_literal_id = function_literal->function_literal_id();
4768 CHECK_NE(function_literal_id, kInvalidInfoId);
4769 // If this check fails, the problem is most probably the function id
4770 // renumbering done by AstFunctionLiteralIdReindexer; in particular, that
4771 // AstTraversalVisitor doesn't recurse properly in the construct which
4772 // triggers the mismatch.
4773 CHECK_LT(function_literal_id, script->infos()->length());
4774 Tagged<MaybeObject> shared = script->infos()->get(function_literal_id);
4775 Tagged<HeapObject> heap_object;
4776 if (!shared.GetHeapObject(&heap_object) ||
4777 IsUndefined(heap_object, isolate)) {
4779 }
4781 isolate);
4782 function_literal->set_shared_function_info(result);
4783 return result;
4784}
4786 DirectHandle<Script> script, Isolate* isolate,
4787 FunctionLiteral* function_literal);
4789 DirectHandle<Script> script, LocalIsolate* isolate,
4790 FunctionLiteral* function_literal);
4791
4793 : iterator_(isolate->heap()->script_list()) {}
4794
4796 Tagged<Object> o = iterator_.Next();
4797 if (o != Tagged<Object>()) {
4798 return Cast<Script>(o);
4799 }
4800 return Script();
4801}
4802
4803// static
4805 int length) {
4806 DCHECK_GE(capacity, 0);
4807 array->GetIsolate()->factory()->NewJSArrayStorage(
4808 array, length, capacity,
4810}
4811
4813 uint32_t new_length) {
4814 if (array->SetLengthWouldNormalize(new_length)) {
4816 }
4817 return array->GetElementsAccessor()->SetLength(array, new_length);
4818}
4819
4820// ES6: 9.5.2 [[SetPrototypeOf]] (V)
4821// static
4824 bool from_javascript,
4825 ShouldThrow should_throw) {
4826 STACK_CHECK(isolate, Nothing<bool>());
4827 DirectHandle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
4828 // 1. Assert: Either Type(V) is Object or Type(V) is Null.
4829 DCHECK(IsJSReceiver(*value) || IsNull(*value, isolate));
4830 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
4831 DirectHandle<Object> handler(proxy->handler(), isolate);
4832 // 3. If handler is null, throw a TypeError exception.
4833 // 4. Assert: Type(handler) is Object.
4834 if (proxy->IsRevoked()) {
4835 isolate->Throw(*isolate->factory()->NewTypeError(
4836 MessageTemplate::kProxyRevoked, trap_name));
4837 return Nothing<bool>();
4838 }
4839 // 5. Let target be the value of the [[ProxyTarget]] internal slot.
4840 DirectHandle<JSReceiver> target(Cast<JSReceiver>(proxy->target()), isolate);
4841 // 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
4844 isolate, trap,
4845 Object::GetMethod(isolate, Cast<JSReceiver>(handler), trap_name),
4846 Nothing<bool>());
4847 // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
4848 if (IsUndefined(*trap, isolate)) {
4849 return JSReceiver::SetPrototype(isolate, target, value, from_javascript,
4850 should_throw);
4851 }
4852 // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
4853 DirectHandle<Object> args[] = {target, value};
4854 DirectHandle<Object> trap_result;
4856 isolate, trap_result,
4857 Execution::Call(isolate, trap, handler, base::VectorOf(args)),
4858 Nothing<bool>());
4859 bool bool_trap_result = Object::BooleanValue(*trap_result, isolate);
4860 // 9. If booleanTrapResult is false, return false.
4861 if (!bool_trap_result) {
4863 isolate, should_throw,
4864 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
4865 }
4866 // 10. Let extensibleTarget be ? IsExtensible(target).
4868 if (is_extensible.IsNothing()) return Nothing<bool>();
4869 // 11. If extensibleTarget is true, return true.
4870 if (is_extensible.FromJust()) {
4871 if (bool_trap_result) return Just(true);
4873 isolate, should_throw,
4874 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
4875 }
4876 // 12. Let targetProto be ? target.[[GetPrototypeOf]]().
4877 DirectHandle<Object> target_proto;
4878 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
4879 JSReceiver::GetPrototype(isolate, target),
4880 Nothing<bool>());
4881 // 13. If SameValue(V, targetProto) is false, throw a TypeError exception.
4882 if (bool_trap_result && !Object::SameValue(*value, *target_proto)) {
4883 isolate->Throw(*isolate->factory()->NewTypeError(
4884 MessageTemplate::kProxySetPrototypeOfNonExtensible));
4885 return Nothing<bool>();
4886 }
4887 // 14. Return true.
4888 return Just(true);
4889}
4890
4892 if (!HasFastElements()) return false;
4893 uint32_t capacity = static_cast<uint32_t>(elements()->length());
4894 uint32_t new_capacity;
4895 return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
4896 ShouldConvertToSlowElements(*this, capacity, new_length - 1,
4897 &new_capacity);
4898}
4899
4901 set_pretenure_decision(kUndecided);
4902 set_memento_found_count(0);
4903 set_memento_create_count(0);
4904}
4905
4907 PretenureDecision mode = pretenure_decision();
4908 // Zombie objects "decide" to be untenured.
4909 return mode == kTenure ? AllocationType::kOld : AllocationType::kYoung;
4910}
4911
4913 DCHECK(v8_flags.trace_track_allocation_sites);
4914 Tagged<Object> current = boilerplate()->GetHeap()->allocation_sites_list();
4915 while (IsAllocationSite(current)) {
4918 if (current_site->nested_site() == this) {
4919 return true;
4920 }
4921 current = current_site->weak_next();
4922 }
4923 return false;
4924}
4925
4930
4932 switch (decision) {
4933 case kUndecided:
4934 return "undecided";
4935 case kDontTenure:
4936 return "don't tenure";
4937 case kMaybeTenure:
4938 return "maybe tenure";
4939 case kTenure:
4940 return "tenure";
4941 case kZombie:
4942 return "zombie";
4943 default:
4944 UNREACHABLE();
4945 }
4946}
4947
4948// static
4950 DCHECK(IsJSArrayMap(js_array_map));
4951 if (js_array_map->is_dictionary_map()) return true;
4952
4953 // Fast path: "length" is the first fast property of arrays with non
4954 // dictionary properties. Since it's not configurable, it's guaranteed to be
4955 // the first in the descriptor array.
4956 InternalIndex first(0);
4957 DCHECK(js_array_map->instance_descriptors()->GetKey(first) ==
4958 GetReadOnlyRoots().length_string());
4959 return js_array_map->instance_descriptors()->GetDetails(first).IsReadOnly();
4960}
4961
4963 Tagged<Map> map = array->map();
4964
4965 // If map guarantees that there can't be a read-only length, we are done.
4966 if (!MayHaveReadOnlyLength(map)) return false;
4967
4968 // Look at the object.
4969 Isolate* isolate = array->GetIsolate();
4970 LookupIterator it(isolate, array, isolate->factory()->length_string(), array,
4973 return it.IsReadOnly();
4974}
4975
4977 uint32_t index) {
4978 uint32_t length = 0;
4979 CHECK(Object::ToArrayLength(array->length(), &length));
4980 if (length <= index) return HasReadOnlyLength(array);
4981 return false;
4982}
4983
4984const char* Symbol::PrivateSymbolToName() const {
4986#define SYMBOL_CHECK_AND_PRINT(_, name) \
4987 if (this == roots.name()) return #name;
4989#undef SYMBOL_CHECK_AND_PRINT
4990 return "UNKNOWN";
4991}
4992
4994 int value = flags() & StatusBits::kMask;
4995 DCHECK(value == 0 || value == 1 || value == 2);
4996 return static_cast<v8::Promise::PromiseState>(value);
4997}
4998
5000 int value = flags() & ~StatusBits::kMask;
5001 set_flags(value | status);
5002}
5003
5004// static
5006 switch (status) {
5008 return "fulfilled";
5010 return "pending";
5012 return "rejected";
5013 }
5014 UNREACHABLE();
5015}
5016
5017// static
5019 DirectHandle<Object> value) {
5020 Isolate* const isolate = promise->GetIsolate();
5021
5022#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
5023 if (isolate->HasContextPromiseHooks()) {
5024 isolate->raw_native_context()->RunPromiseHook(
5025 PromiseHookType::kResolve, indirect_handle(promise, isolate),
5026 isolate->factory()->undefined_value());
5027 }
5028#endif
5029
5030 // 1. Assert: The value of promise.[[PromiseState]] is "pending".
5031 CHECK_EQ(Promise::kPending, promise->status());
5032
5033 // 2. Let reactions be promise.[[PromiseFulfillReactions]].
5034 DirectHandle<Object> reactions(promise->reactions(), isolate);
5035
5036 // 3. Set promise.[[PromiseResult]] to value.
5037 // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
5038 // 5. Set promise.[[PromiseRejectReactions]] to undefined.
5039 promise->set_reactions_or_result(Cast<JSAny>(*value));
5040
5041 // 6. Set promise.[[PromiseState]] to "fulfilled".
5042 promise->set_status(Promise::kFulfilled);
5043
5044 // 7. Return TriggerPromiseReactions(reactions, value).
5045 return TriggerPromiseReactions(isolate, reactions, value,
5047}
5048
5049static void MoveMessageToPromise(Isolate* isolate,
5050 DirectHandle<JSPromise> promise) {
5051 if (!isolate->has_pending_message()) return;
5052
5053 if (isolate->debug()->is_active()) {
5054 DirectHandle<Object> message(isolate->pending_message(), isolate);
5056 isolate->factory()->promise_debug_message_symbol();
5057 Object::SetProperty(isolate, promise, key, message,
5060 .Assert();
5061 }
5062
5063 // The message object for a rejected promise was only stored for this purpose.
5064 // Clear it, otherwise we might leak memory.
5065 isolate->clear_pending_message();
5066}
5067
5068// static
5070 DirectHandle<Object> reason,
5071 bool debug_event) {
5072 Isolate* const isolate = promise->GetIsolate();
5073 DCHECK(
5074 !reinterpret_cast<v8::Isolate*>(isolate)->GetCurrentContext().IsEmpty());
5075
5076 MoveMessageToPromise(isolate, promise);
5077
5078 if (debug_event) isolate->debug()->OnPromiseReject(promise, reason);
5079 isolate->RunAllPromiseHooks(PromiseHookType::kResolve, promise,
5080 isolate->factory()->undefined_value());
5081
5082 // 1. Assert: The value of promise.[[PromiseState]] is "pending".
5083 CHECK_EQ(Promise::kPending, promise->status());
5084
5085 // 2. Let reactions be promise.[[PromiseRejectReactions]].
5086 DirectHandle<Object> reactions(promise->reactions(), isolate);
5087
5088 // 3. Set promise.[[PromiseResult]] to reason.
5089 // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
5090 // 5. Set promise.[[PromiseRejectReactions]] to undefined.
5091 promise->set_reactions_or_result(Cast<JSAny>(*reason));
5092
5093 // 6. Set promise.[[PromiseState]] to "rejected".
5094 promise->set_status(Promise::kRejected);
5095
5096 // 7. If promise.[[PromiseIsHandled]] is false, perform
5097 // HostPromiseRejectionTracker(promise, "reject").
5098 if (!promise->has_handler()) {
5099 isolate->ReportPromiseReject(promise, reason, kPromiseRejectWithNoHandler);
5100 }
5101
5102 // 8. Return TriggerPromiseReactions(reactions, reason).
5103 return TriggerPromiseReactions(isolate, reactions, reason,
5105}
5106
5107// https://tc39.es/ecma262/#sec-promise-resolve-functions
5108// static
5110 DirectHandle<Object> resolution_obj) {
5111 Isolate* const isolate = promise->GetIsolate();
5112 DCHECK(
5113 !reinterpret_cast<v8::Isolate*>(isolate)->GetCurrentContext().IsEmpty());
5114
5115 isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
5116 isolate->factory()->undefined_value());
5117
5118 // 7. If SameValue(resolution, promise) is true, then
5119 if (promise.is_identical_to(resolution_obj)) {
5120 // a. Let selfResolutionError be a newly created TypeError object.
5121 DirectHandle<Object> self_resolution_error =
5122 isolate->factory()->NewTypeError(MessageTemplate::kPromiseCyclic,
5123 resolution_obj);
5124 // b. Return RejectPromise(promise, selfResolutionError).
5125 return Reject(promise, self_resolution_error);
5126 }
5127
5128 // 8. If Type(resolution) is not Object, then
5129 DirectHandle<JSReceiver> resolution_recv;
5130 if (!TryCast<JSReceiver>(resolution_obj, &resolution_recv)) {
5131 // a. Return FulfillPromise(promise, resolution).
5132 return Fulfill(promise, resolution_obj);
5133 }
5134
5135 // 9. Let then be Get(resolution, "then").
5137
5138 // Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
5139 // initial %PromisePrototype% yields the initial method. In addition this
5140 // protector also guards the negative lookup of "then" on the intrinsic
5141 // %ObjectPrototype%, meaning that such lookups are guaranteed to yield
5142 // undefined without triggering any side-effects.
5143 if (IsJSPromise(*resolution_recv) &&
5144 resolution_recv->map()->prototype()->map()->instance_type() ==
5145 JS_PROMISE_PROTOTYPE_TYPE &&
5146 Protectors::IsPromiseThenLookupChainIntact(isolate)) {
5147 // We can skip the "then" lookup on {resolution} if its [[Prototype]]
5148 // is the (initial) Promise.prototype and the Promise#then protector
5149 // is intact, as that guards the lookup path for the "then" property
5150 // on JSPromise instances which have the (initial) %PromisePrototype%.
5151 then = isolate->promise_then();
5152 } else {
5153 then = JSReceiver::GetProperty(isolate, resolution_recv,
5154 isolate->factory()->then_string());
5155 }
5156
5157 // 10. If then is an abrupt completion, then
5158 DirectHandle<Object> then_action;
5159 if (!then.ToHandle(&then_action)) {
5160 // The "then" lookup can cause termination.
5161 if (!isolate->is_catchable_by_javascript(isolate->exception())) {
5162 return kNullMaybeHandle;
5163 }
5164
5165 // a. Return RejectPromise(promise, then.[[Value]]).
5166 DirectHandle<Object> reason(isolate->exception(), isolate);
5167 isolate->clear_exception();
5168 return Reject(promise, reason, false);
5169 }
5170
5171 // 11. Let thenAction be then.[[Value]].
5172 // 12. If IsCallable(thenAction) is false, then
5173 if (!IsCallable(*then_action)) {
5174 // a. Return FulfillPromise(promise, resolution).
5175 return Fulfill(promise, resolution_recv);
5176 }
5177
5178 // 13. Let job be NewPromiseResolveThenableJob(promise, resolution,
5179 // thenAction).
5180 DirectHandle<NativeContext> then_context;
5182 .ToHandle(&then_context)) {
5183 then_context = isolate->native_context();
5184 }
5185
5187 isolate->factory()->NewPromiseResolveThenableJobTask(
5188 promise, resolution_recv, Cast<JSReceiver>(then_action),
5189 then_context);
5190 if (isolate->debug()->is_active() && IsJSPromise(*resolution_recv)) {
5191 // Mark the dependency of the new {promise} on the {resolution}.
5192 Object::SetProperty(isolate, resolution_recv,
5193 isolate->factory()->promise_handled_by_symbol(),
5194 promise)
5195 .Check();
5196 }
5197 MicrotaskQueue* microtask_queue = then_context->microtask_queue();
5198 if (microtask_queue) microtask_queue->EnqueueMicrotask(*task);
5199
5200 // 15. Return undefined.
5201 return isolate->factory()->undefined_value();
5202}
5203
5204// static
5206 Isolate* isolate, DirectHandle<Object> reactions,
5208 CHECK(IsSmi(*reactions) || IsPromiseReaction(*reactions));
5209
5210 // We need to reverse the {reactions} here, since we record them
5211 // on the JSPromise in the reverse order.
5212 {
5217 while (!IsSmi(current)) {
5219 Cast<PromiseReaction>(current)->next();
5220 Cast<PromiseReaction>(current)->set_next(reversed);
5221 reversed = current;
5222 current = next;
5223 }
5224 reactions = direct_handle(reversed, isolate);
5225 }
5226
5227 // Morph the {reactions} into PromiseReactionJobTasks
5228 // and push them onto the microtask queue.
5229 while (!IsSmi(*reactions)) {
5230 auto task = Cast<HeapObject>(reactions);
5231 auto reaction = Cast<PromiseReaction>(task);
5232 reactions = direct_handle(reaction->next(), isolate);
5233
5234 // According to HTML, we use the context of the appropriate handler as the
5235 // context of the microtask. See step 3 of HTML's EnqueueJob:
5236 // https://html.spec.whatwg.org/C/#enqueuejob(queuename,-job,-arguments)
5237 DirectHandle<NativeContext> handler_context;
5238
5241 if (type == PromiseReaction::kFulfill) {
5242 primary_handler = direct_handle(reaction->fulfill_handler(), isolate);
5243 secondary_handler = direct_handle(reaction->reject_handler(), isolate);
5244 } else {
5245 primary_handler = direct_handle(reaction->reject_handler(), isolate);
5246 secondary_handler = direct_handle(reaction->fulfill_handler(), isolate);
5247 }
5248
5249 bool has_handler_context = false;
5250 if (IsJSReceiver(*primary_handler)) {
5251 has_handler_context =
5253 .ToHandle(&handler_context);
5254 }
5255 if (!has_handler_context && IsJSReceiver(*secondary_handler)) {
5256 has_handler_context = JSReceiver::GetContextForMicrotask(
5257 Cast<JSReceiver>(secondary_handler))
5258 .ToHandle(&handler_context);
5259 }
5260 if (!has_handler_context) handler_context = isolate->native_context();
5261
5262 static_assert(
5263 static_cast<int>(PromiseReaction::kSize) ==
5264 static_cast<int>(
5266 if (type == PromiseReaction::kFulfill) {
5267 task->set_map(
5268 isolate,
5269 ReadOnlyRoots(isolate).promise_fulfill_reaction_job_task_map(),
5271 Cast<PromiseFulfillReactionJobTask>(task)->set_argument(*argument);
5272 Cast<PromiseFulfillReactionJobTask>(task)->set_context(*handler_context);
5273 static_assert(
5274 static_cast<int>(PromiseReaction::kFulfillHandlerOffset) ==
5275 static_cast<int>(PromiseFulfillReactionJobTask::kHandlerOffset));
5276 static_assert(
5277 static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
5278 static_cast<int>(
5279 PromiseFulfillReactionJobTask::kPromiseOrCapabilityOffset));
5280#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
5281 static_assert(
5282 static_cast<int>(
5283 PromiseReaction::kContinuationPreservedEmbedderDataOffset) ==
5284 static_cast<int>(PromiseFulfillReactionJobTask::
5285 kContinuationPreservedEmbedderDataOffset));
5286#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
5287 } else {
5289 task->set_map(
5290 isolate,
5291 ReadOnlyRoots(isolate).promise_reject_reaction_job_task_map(),
5293 Cast<PromiseRejectReactionJobTask>(task)->set_argument(*argument);
5294 Cast<PromiseRejectReactionJobTask>(task)->set_context(*handler_context);
5295 Cast<PromiseRejectReactionJobTask>(task)->set_handler(*primary_handler);
5296 static_assert(
5297 static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
5298 static_cast<int>(
5299 PromiseRejectReactionJobTask::kPromiseOrCapabilityOffset));
5300#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
5301 static_assert(
5302 static_cast<int>(
5303 PromiseReaction::kContinuationPreservedEmbedderDataOffset) ==
5304 static_cast<int>(PromiseRejectReactionJobTask::
5305 kContinuationPreservedEmbedderDataOffset));
5306#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
5307 }
5308
5309 MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
5310 if (microtask_queue) {
5311 microtask_queue->EnqueueMicrotask(*Cast<PromiseReactionJobTask>(task));
5312 }
5313 }
5314
5315 return isolate->factory()->undefined_value();
5316}
5317
5318#ifdef V8_LOWER_LIMITS_MODE
5319const uint32_t EphemeronHashTableShape::kHashBits = 10;
5320#else
5323#endif // V8_LOWER_LIMITS_MODE
5324
5325template <typename Derived, typename Shape>
5326void HashTable<Derived, Shape>::IteratePrefix(ObjectVisitor* v) {
5327 BodyDescriptorBase::IteratePointers(this, 0, kElementsStartOffset, v);
5328}
5329
5330template <typename Derived, typename Shape>
5331void HashTable<Derived, Shape>::IterateElements(ObjectVisitor* v) {
5332 BodyDescriptorBase::IteratePointers(this, kElementsStartOffset,
5333 SizeFor(length()), v);
5334}
5335
5336template <typename Derived, typename Shape>
5337template <typename IsolateT>
5338Handle<Derived> HashTable<Derived, Shape>::New(
5339 IsolateT* isolate, int at_least_space_for, AllocationType allocation,
5340 MinimumCapacity capacity_option) {
5341 DCHECK_LE(0, at_least_space_for);
5343 base::bits::IsPowerOfTwo(at_least_space_for));
5344
5345 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
5346 ? at_least_space_for
5347 : ComputeCapacity(at_least_space_for);
5348 if (capacity > HashTable::kMaxCapacity) {
5349 isolate->FatalProcessOutOfHeapMemory("invalid table size");
5350 }
5351 return NewInternal(isolate, capacity, allocation);
5352}
5353
5354template <typename Derived, typename Shape>
5355template <typename IsolateT>
5356Handle<Derived> HashTable<Derived, Shape>::NewInternal(
5357 IsolateT* isolate, int capacity, AllocationType allocation) {
5358 auto* factory = isolate->factory();
5359 int length = EntryToIndex(InternalIndex(capacity));
5360 Handle<FixedArray> array = factory->NewFixedArrayWithMap(
5361 Derived::GetMap(isolate->roots_table()), length, allocation);
5362 Handle<Derived> table = Cast<Derived>(array);
5364 Tagged<Derived> raw_table = *table;
5365 raw_table->SetNumberOfElements(0);
5366 raw_table->SetNumberOfDeletedElements(0);
5367 raw_table->SetCapacity(capacity);
5368 return table;
5369}
5370
5371template <typename Derived, typename Shape>
5372void HashTable<Derived, Shape>::Rehash(PtrComprCageBase cage_base,
5373 Tagged<Derived> new_table) {
5375 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
5376
5377 DCHECK_LT(NumberOfElements(), new_table->Capacity());
5378
5379 // Copy prefix to new array.
5380 for (int i = kPrefixStartIndex; i < kElementsStartIndex; i++) {
5381 new_table->set(i, get(i), mode);
5382 }
5383
5384 // Rehash the elements.
5385 ReadOnlyRoots roots = GetReadOnlyRoots();
5386 for (InternalIndex i : this->IterateEntries()) {
5387 uint32_t from_index = EntryToIndex(i);
5388 Tagged<Object> k = this->get(from_index);
5389 if (!IsKey(roots, k)) continue;
5390 uint32_t hash = TodoShape::HashForObject(roots, k);
5391 uint32_t insertion_index =
5392 EntryToIndex(new_table->FindInsertionEntry(cage_base, roots, hash));
5393 new_table->set_key(insertion_index, get(from_index), mode);
5394 for (int j = 1; j < TodoShape::kEntrySize; j++) {
5395 new_table->set(insertion_index + j, get(from_index + j), mode);
5396 }
5397 }
5398 new_table->SetNumberOfElements(NumberOfElements());
5399 new_table->SetNumberOfDeletedElements(0);
5400}
5401
5402template <typename Derived, typename Shape>
5403InternalIndex HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots,
5405 int probe,
5406 InternalIndex expected) {
5407 uint32_t hash = TodoShape::HashForObject(roots, k);
5408 uint32_t capacity = this->Capacity();
5409 InternalIndex entry = FirstProbe(hash, capacity);
5410 for (int i = 1; i < probe; i++) {
5411 if (entry == expected) return expected;
5412 entry = NextProbe(entry, i, capacity);
5413 }
5414 return entry;
5415}
5416
5417template <typename Derived, typename Shape>
5418void HashTable<Derived, Shape>::Swap(InternalIndex entry1, InternalIndex entry2,
5419 WriteBarrierMode mode) {
5420 int index1 = EntryToIndex(entry1);
5421 int index2 = EntryToIndex(entry2);
5422 Tagged<Object> temp[TodoShape::kEntrySize];
5423 Derived* self = static_cast<Derived*>(this);
5424 for (int j = 0; j < TodoShape::kEntrySize; j++) {
5425 temp[j] = get(index1 + j);
5426 }
5427 self->set_key(index1, get(index2), mode);
5428 for (int j = 1; j < TodoShape::kEntrySize; j++) {
5429 set(index1 + j, get(index2 + j), mode);
5430 }
5431 self->set_key(index2, temp[0], mode);
5432 for (int j = 1; j < TodoShape::kEntrySize; j++) {
5433 set(index2 + j, temp[j], mode);
5434 }
5435}
5436
5437template <typename Derived, typename Shape>
5438void HashTable<Derived, Shape>::Rehash(PtrComprCageBase cage_base) {
5440 WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
5441 ReadOnlyRoots roots = EarlyGetReadOnlyRoots();
5442 uint32_t capacity = Capacity();
5443 bool done = false;
5444 for (int probe = 1; !done; probe++) {
5445 // All elements at entries given by one of the first _probe_ probes
5446 // are placed correctly. Other elements might need to be moved.
5447 done = true;
5448 for (InternalIndex current(0); current.raw_value() < capacity;
5449 /* {current} is advanced manually below, when appropriate.*/) {
5450 Tagged<Object> current_key = KeyAt(cage_base, current);
5451 if (!IsKey(roots, current_key)) {
5452 ++current; // Advance to next entry.
5453 continue;
5454 }
5455 InternalIndex target = EntryForProbe(roots, current_key, probe, current);
5456 if (current == target) {
5457 ++current; // Advance to next entry.
5458 continue;
5459 }
5460 Tagged<Object> target_key = KeyAt(cage_base, target);
5461 if (!IsKey(roots, target_key) ||
5462 EntryForProbe(roots, target_key, probe, target) != target) {
5463 // Put the current element into the correct position.
5464 Swap(current, target, mode);
5465 // The other element will be processed on the next iteration,
5466 // so don't advance {current} here!
5467 } else {
5468 // The place for the current element is occupied. Leave the element
5469 // for the next probe.
5470 done = false;
5471 ++current; // Advance to next entry.
5472 }
5473 }
5474 }
5475 // Wipe deleted entries.
5476 Tagged<Object> the_hole = roots.the_hole_value();
5477 Tagged<HeapObject> undefined = roots.undefined_value();
5478 Derived* self = static_cast<Derived*>(this);
5479 for (InternalIndex current : InternalIndex::Range(capacity)) {
5480 if (KeyAt(cage_base, current) == the_hole) {
5481 self->set_key(EntryToIndex(current) + kEntryKeyIndex, undefined,
5483 }
5484 }
5485 SetNumberOfDeletedElements(0);
5486}
5487
5488template <typename Derived, typename Shape>
5489template <typename IsolateT, template <typename> typename HandleType>
5490 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5491HandleType<Derived> HashTable<Derived, Shape>::EnsureCapacity(
5492 IsolateT* isolate, HandleType<Derived> table, int n,
5493 AllocationType allocation) {
5494 if (table->HasSufficientCapacityToAdd(n)) return table;
5495
5496 int capacity = table->Capacity();
5497 int new_nof = table->NumberOfElements() + n;
5498
5499 bool should_pretenure = allocation == AllocationType::kOld ||
5500 ((capacity > kMinCapacityForPretenure) &&
5502 HandleType<Derived> new_table = HashTable::New(
5503 isolate, new_nof,
5504 should_pretenure ? AllocationType::kOld : AllocationType::kYoung);
5505
5506 table->Rehash(isolate, *new_table);
5507 return new_table;
5508}
5509
5510template <typename Derived, typename Shape>
5511bool HashTable<Derived, Shape>::HasSufficientCapacityToAdd(
5512 int number_of_additional_elements) {
5513 return HasSufficientCapacityToAdd(Capacity(), NumberOfElements(),
5514 NumberOfDeletedElements(),
5515 number_of_additional_elements);
5516}
5517
5518// static
5519template <typename Derived, typename Shape>
5520bool HashTable<Derived, Shape>::HasSufficientCapacityToAdd(
5521 int capacity, int number_of_elements, int number_of_deleted_elements,
5522 int number_of_additional_elements) {
5523 int nof = number_of_elements + number_of_additional_elements;
5524 // Return true if:
5525 // 50% is still free after adding number_of_additional_elements elements and
5526 // at most 50% of the free elements are deleted elements.
5527 if ((nof < capacity) &&
5528 ((number_of_deleted_elements <= (capacity - nof) / 2))) {
5529 int needed_free = nof / 2;
5530 if (nof + needed_free <= capacity) return true;
5531 }
5532 return false;
5533}
5534
5535// static
5536template <typename Derived, typename Shape>
5537int HashTable<Derived, Shape>::ComputeCapacityWithShrink(
5538 int current_capacity, int at_least_room_for) {
5539 // Shrink to fit the number of elements if only a quarter of the
5540 // capacity is filled with elements.
5541 if (at_least_room_for > (current_capacity / 4)) return current_capacity;
5542 // Recalculate the smaller capacity actually needed.
5543 int new_capacity = ComputeCapacity(at_least_room_for);
5544 DCHECK_GE(new_capacity, at_least_room_for);
5545 // Don't go lower than room for {kMinShrinkCapacity} elements.
5546 if (new_capacity < Derived::kMinShrinkCapacity) return current_capacity;
5547 return new_capacity;
5548}
5549
5550// static
5551template <typename Derived, typename Shape>
5552template <template <typename> typename HandleType>
5553 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5554HandleType<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
5555 HandleType<Derived> table,
5556 int additional_capacity) {
5557 int new_capacity = ComputeCapacityWithShrink(
5558 table->Capacity(), table->NumberOfElements() + additional_capacity);
5559 if (new_capacity == table->Capacity()) return table;
5560 DCHECK_GE(new_capacity, Derived::kMinShrinkCapacity);
5561
5562 bool pretenure = (new_capacity > kMinCapacityForPretenure) &&
5564 HandleType<Derived> new_table =
5565 HashTable::New(isolate, new_capacity,
5568
5569 table->Rehash(isolate, *new_table);
5570 return new_table;
5571}
5572
5573template <typename Derived, typename Shape>
5574InternalIndex HashTable<Derived, Shape>::FindInsertionEntry(
5575 PtrComprCageBase cage_base, ReadOnlyRoots roots, uint32_t hash) {
5576 uint32_t capacity = Capacity();
5577 uint32_t count = 1;
5578 // EnsureCapacity will guarantee the hash table is never full.
5579 for (InternalIndex entry = FirstProbe(hash, capacity);;
5580 entry = NextProbe(entry, count++, capacity)) {
5581 if (!IsKey(roots, KeyAt(cage_base, entry))) return entry;
5582 }
5583}
5584
5585std::optional<Tagged<PropertyCell>>
5587 Isolate* isolate, DirectHandle<Name> name, RelaxedLoadTag tag) {
5588 // This reimplements HashTable::FindEntry for use in a concurrent setting.
5589 // 1) Atomic loads.
5590 // 2) IsPendingAllocation checks.
5591 // 3) Return the PropertyCell value instead of the InternalIndex to avoid a
5592 // repeated load (unsafe with concurrent modifications).
5593
5595 PtrComprCageBase cage_base{isolate};
5596 ReadOnlyRoots roots(isolate);
5597 const int32_t hash = TodoShape::Hash(roots, name);
5598 const uint32_t capacity = Capacity();
5599 uint32_t count = 1;
5600 Tagged<Object> undefined = roots.undefined_value();
5601 Tagged<Object> the_hole = roots.the_hole_value();
5602 // EnsureCapacity will guarantee the hash table is never full.
5603 for (InternalIndex entry = FirstProbe(hash, capacity);;
5604 entry = NextProbe(entry, count++, capacity)) {
5605 Tagged<Object> element = KeyAt(cage_base, entry, kRelaxedLoad);
5606 if (isolate->heap()->IsPendingAllocation(element)) return {};
5607 if (element == undefined) return {};
5608 if (TodoShape::kMatchNeedsHoleCheck && element == the_hole) continue;
5609 if (!TodoShape::IsMatch(name, element)) continue;
5610 CHECK(IsPropertyCell(element, cage_base));
5611 return Cast<PropertyCell>(element);
5612 }
5613}
5614
5616 return HashTable::New(isolate, 0);
5617}
5618
5620 DirectHandle<String> name) {
5621 if (!stringset->Has(isolate, name)) {
5622 stringset = EnsureCapacity(isolate, stringset);
5623 uint32_t hash = TodoShape::Hash(ReadOnlyRoots(isolate), *name);
5624 InternalIndex entry = stringset->FindInsertionEntry(isolate, hash);
5625 stringset->set(EntryToIndex(entry), *name);
5626 stringset->ElementAdded();
5627 }
5628 return stringset;
5629}
5630
5632 return FindEntry(isolate, *name).is_found();
5633}
5634
5636 Isolate* isolate, Handle<RegisteredSymbolTable> table,
5638 // Validate that the key is absent.
5639 SLOW_DCHECK(table->FindEntry(isolate, key).is_not_found());
5640
5641 table = EnsureCapacity(isolate, table);
5642 uint32_t hash = TodoShape::Hash(ReadOnlyRoots(isolate), key);
5643 InternalIndex entry = table->FindInsertionEntry(isolate, hash);
5644 table->set(EntryToIndex(entry), *key);
5645 table->set(EntryToValueIndex(entry), *symbol);
5646 table->ElementAdded();
5647 return table;
5648}
5649
5650template <typename Derived, typename Shape>
5651template <typename IsolateT>
5652Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
5653 IsolateT* isolate, int at_least_space_for, AllocationType allocation,
5654 MinimumCapacity capacity_option) {
5655 DCHECK_LE(0, at_least_space_for);
5656 Handle<Derived> dict = Dictionary<Derived, Shape>::New(
5657 isolate, at_least_space_for, allocation, capacity_option);
5658 dict->SetHash(PropertyArray::kNoHashSentinel);
5659 dict->set_next_enumeration_index(PropertyDetails::kInitialIndex);
5660 return dict;
5661}
5662
5663template <typename IsolateT>
5665 int at_least_space_for,
5666 AllocationType allocation,
5667 MinimumCapacity capacity_option) {
5669 BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
5670 isolate, at_least_space_for, allocation, capacity_option);
5671 dict->set_flags(kFlagsDefault);
5672 return dict;
5673}
5674
5675template <typename Derived, typename Shape>
5676int BaseNameDictionary<Derived, Shape>::NextEnumerationIndex(
5677 Isolate* isolate, DirectHandle<Derived> dictionary) {
5678 int index = dictionary->next_enumeration_index();
5679 // Check whether the next enumeration index is valid.
5680 if (!PropertyDetails::IsValidIndex(index)) {
5681 // If not, we generate new indices for the properties.
5682 DirectHandle<FixedArray> iteration_order =
5683 IterationIndices(isolate, dictionary);
5684 int length = iteration_order->length();
5685 DCHECK_LE(length, dictionary->NumberOfElements());
5686
5687 // Iterate over the dictionary using the enumeration order and update
5688 // the dictionary with new enumeration indices.
5689 for (int i = 0; i < length; i++) {
5690 InternalIndex internal_index(Smi::ToInt(iteration_order->get(i)));
5691 DCHECK(dictionary->IsKey(GetReadOnlyRoots(),
5692 dictionary->KeyAt(isolate, internal_index)));
5693
5694 int enum_index = PropertyDetails::kInitialIndex + i;
5695
5696 PropertyDetails details = dictionary->DetailsAt(internal_index);
5697 PropertyDetails new_details = details.set_index(enum_index);
5698 dictionary->DetailsAtPut(internal_index, new_details);
5699 }
5700
5702 }
5703
5704 // Don't update the next enumeration index here, since we might be looking at
5705 // an immutable empty dictionary.
5706 return index;
5707}
5708
5709template <typename Derived, typename Shape>
5710template <template <typename> typename HandleType>
5711 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5712HandleType<Derived> Dictionary<Derived, Shape>::DeleteEntry(
5713 Isolate* isolate, HandleType<Derived> dictionary, InternalIndex entry) {
5714 DCHECK(TodoShape::kEntrySize != 3 ||
5715 dictionary->DetailsAt(entry).IsConfigurable());
5716 dictionary->ClearEntry(entry);
5717 dictionary->ElementRemoved();
5718 return Shrink(isolate, dictionary);
5719}
5720
5721template <typename Derived, typename Shape>
5722template <template <typename> typename HandleType>
5723 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5724HandleType<Derived> Dictionary<Derived, Shape>::AtPut(
5725 Isolate* isolate, HandleType<Derived> dictionary, Key key,
5726 DirectHandle<Object> value, PropertyDetails details) {
5727 InternalIndex entry = dictionary->FindEntry(isolate, key);
5728
5729 // If the entry is present set the value;
5730 if (entry.is_not_found()) {
5731 return Derived::Add(isolate, dictionary, key, value, details);
5732 }
5733
5734 // We don't need to copy over the enumeration index.
5735 dictionary->ValueAtPut(entry, *value);
5736 if (TodoShape::kEntrySize == 3) dictionary->DetailsAtPut(entry, details);
5737 return dictionary;
5738}
5739
5740template <typename Derived, typename Shape>
5741void Dictionary<Derived, Shape>::UncheckedAtPut(
5742 Isolate* isolate, DirectHandle<Derived> dictionary, Key key,
5743 DirectHandle<Object> value, PropertyDetails details) {
5744 InternalIndex entry = dictionary->FindEntry(isolate, key);
5745
5746 // If the entry is present set the value;
5747 if (entry.is_not_found()) {
5748 Derived::UncheckedAdd(isolate, dictionary, key, value, details);
5749 } else {
5750 // We don't need to copy over the enumeration index.
5751 dictionary->ValueAtPut(entry, *value);
5752 if (TodoShape::kEntrySize == 3) dictionary->DetailsAtPut(entry, details);
5753 }
5754}
5755
5756template <typename Derived, typename Shape>
5757template <typename IsolateT, template <typename> typename HandleType>
5758 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5759HandleType<Derived>
5760BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex(
5761 IsolateT* isolate, HandleType<Derived> dictionary, Key key,
5762 DirectHandle<Object> value, PropertyDetails details,
5763 InternalIndex* entry_out) {
5764 // Insert element at empty or deleted entry.
5765 return Dictionary<Derived, Shape>::Add(isolate, dictionary, key, value,
5766 details, entry_out);
5767}
5768
5769template <typename Derived, typename Shape>
5770template <template <typename> typename HandleType>
5771 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5772HandleType<Derived> BaseNameDictionary<Derived, Shape>::Add(
5773 Isolate* isolate, HandleType<Derived> dictionary, Key key,
5774 DirectHandle<Object> value, PropertyDetails details,
5775 InternalIndex* entry_out) {
5776 // Insert element at empty or deleted entry
5777 DCHECK_EQ(0, details.dictionary_index());
5778 // Assign an enumeration index to the property and update
5779 // SetNextEnumerationIndex.
5780 int index = Derived::NextEnumerationIndex(isolate, dictionary);
5781 details = details.set_index(index);
5782 dictionary = AddNoUpdateNextEnumerationIndex(isolate, dictionary, key, value,
5783 details, entry_out);
5784 // Update enumeration index here in order to avoid potential modification of
5785 // the canonical empty dictionary which lives in read only space.
5786 dictionary->set_next_enumeration_index(index + 1);
5787 return dictionary;
5788}
5789
5790template <typename Derived, typename Shape>
5791template <typename IsolateT, template <typename> typename HandleType,
5792 AllocationType key_allocation>
5793 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5794HandleType<Derived> Dictionary<Derived, Shape>::Add(
5795 IsolateT* isolate, HandleType<Derived> dictionary, Key key,
5796 DirectHandle<Object> value, PropertyDetails details,
5797 InternalIndex* entry_out) {
5798 ReadOnlyRoots roots(isolate);
5799 uint32_t hash = TodoShape::Hash(roots, key);
5800 // Validate that the key is absent.
5801 SLOW_DCHECK(dictionary->FindEntry(isolate, key).is_not_found());
5802 // Check whether the dictionary should be extended.
5803 dictionary = Derived::EnsureCapacity(isolate, dictionary);
5804
5805 // Compute the key object.
5806 DirectHandle<Object> k =
5807 TodoShape::template AsHandle<key_allocation>(isolate, key);
5808
5809 InternalIndex entry = dictionary->FindInsertionEntry(isolate, roots, hash);
5810 dictionary->SetEntry(entry, *k, *value, details);
5811 DCHECK(IsNumber(dictionary->KeyAt(isolate, entry)) ||
5812 IsUniqueName(TodoShape::Unwrap(dictionary->KeyAt(isolate, entry))));
5813 dictionary->ElementAdded();
5814 if (entry_out) *entry_out = entry;
5815 return dictionary;
5816}
5817
5818template <typename Derived, typename Shape>
5819template <typename IsolateT, template <typename> typename HandleType,
5820 AllocationType key_allocation>
5821 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
5822void Dictionary<Derived, Shape>::UncheckedAdd(IsolateT* isolate,
5823 HandleType<Derived> dictionary,
5824 Key key,
5825 DirectHandle<Object> value,
5826 PropertyDetails details) {
5827 ReadOnlyRoots roots(isolate);
5828 uint32_t hash = TodoShape::Hash(roots, key);
5829 // Validate that the key is absent and we capacity is sufficient.
5830 SLOW_DCHECK(dictionary->FindEntry(isolate, key).is_not_found());
5831 DCHECK(dictionary->HasSufficientCapacityToAdd(1));
5832
5833 // Compute the key object.
5834 DirectHandle<Object> k =
5835 TodoShape::template AsHandle<key_allocation>(isolate, key);
5836
5837 InternalIndex entry = dictionary->FindInsertionEntry(isolate, roots, hash);
5838 dictionary->SetEntry(entry, *k, *value, details);
5839 DCHECK(IsNumber(dictionary->KeyAt(isolate, entry)) ||
5840 IsUniqueName(TodoShape::Unwrap(dictionary->KeyAt(isolate, entry))));
5841}
5842
5843template <typename Derived, typename Shape>
5844Handle<Derived> Dictionary<Derived, Shape>::ShallowCopy(
5845 Isolate* isolate, DirectHandle<Derived> dictionary,
5846 AllocationType allocation) {
5847 return Cast<Derived>(isolate->factory()->CopyFixedArrayWithMap(
5848 dictionary, Derived::GetMap(isolate->roots_table()), allocation));
5849}
5850
5851// static
5853 Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key,
5854 DirectHandle<Object> value) {
5855 return AtPut(isolate, dictionary, key, value, PropertyDetails::Empty());
5856}
5857
5859 uint32_t key, DirectHandle<JSObject> dictionary_holder) {
5861 // If the dictionary requires slow elements an element has already
5862 // been added at a high index.
5863 if (requires_slow_elements()) return;
5864 // Check if this index is high enough that we should require slow
5865 // elements.
5866 if (key > kRequiresSlowElementsLimit) {
5867 if (!dictionary_holder.is_null()) {
5868 dictionary_holder->RequireSlowElements(this);
5869 }
5870 set_requires_slow_elements();
5871 return;
5872 }
5873 // Update max key value.
5874 Tagged<Object> max_index_object = get(kMaxNumberKeyIndex);
5875 if (!IsSmi(max_index_object) || max_number_key() < key) {
5876 FixedArray::set(kMaxNumberKeyIndex,
5877 Smi::FromInt(key << kRequiresSlowElementsTagSize));
5878 }
5879}
5880
5881template <template <typename> typename HandleType>
5882 requires(std::is_convertible_v<HandleType<NumberDictionary>,
5884HandleType<NumberDictionary> NumberDictionary::Set(
5885 Isolate* isolate, HandleType<NumberDictionary> dictionary, uint32_t key,
5886 DirectHandle<Object> value, DirectHandle<JSObject> dictionary_holder,
5887 PropertyDetails details) {
5888 // We could call Set with empty dictionaries. UpdateMaxNumberKey doesn't
5889 // expect empty dictionaries so make sure to call AtPut that correctly handles
5890 // them by creating new dictionary when required.
5891 HandleType<NumberDictionary> new_dictionary =
5892 AtPut(isolate, dictionary, key, value, details);
5893 new_dictionary->UpdateMaxNumberKey(key, dictionary_holder);
5894 return new_dictionary;
5895}
5896
5898 Isolate* isolate, DirectHandle<NumberDictionary> dictionary, uint32_t key,
5899 DirectHandle<Object> value, DirectHandle<JSObject> dictionary_holder,
5900 PropertyDetails details);
5902 Isolate* isolate, IndirectHandle<NumberDictionary> dictionary, uint32_t key,
5903 DirectHandle<Object> value, DirectHandle<JSObject> dictionary_holder,
5904 PropertyDetails details);
5905
5906// static
5909 uint32_t key, DirectHandle<Object> value) {
5910 UncheckedAtPut(isolate, dictionary, key, value, PropertyDetails::Empty());
5911}
5912
5915 int pos = 0;
5917 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
5918 for (InternalIndex i : this->IterateEntries()) {
5920 if (this->ToKey(roots, i, &k)) {
5921 elements->set(pos++, this->ValueAt(i), mode);
5922 }
5923 }
5924 DCHECK_EQ(pos, elements->length());
5925}
5926
5927template <typename Derived, typename Shape>
5928int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
5930 int result = 0;
5931 for (InternalIndex i : this->IterateEntries()) {
5933 if (!this->ToKey(roots, i, &k)) continue;
5934 if (Object::FilterKey(k, ENUMERABLE_STRINGS)) continue;
5935 PropertyDetails details = this->DetailsAt(i);
5936 PropertyAttributes attr = details.attributes();
5937 if ((int{attr} & ONLY_ENUMERABLE) == 0) result++;
5938 }
5939 return result;
5940}
5941
5942template <typename Derived, typename Shape>
5943DirectHandle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
5944 Isolate* isolate, DirectHandle<Derived> dictionary) {
5945 DirectHandle<FixedArray> array =
5946 isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
5947 ReadOnlyRoots roots(isolate);
5948 int array_size = 0;
5949 {
5951 Tagged<Derived> raw_dictionary = *dictionary;
5952 for (InternalIndex i : dictionary->IterateEntries()) {
5954 if (!raw_dictionary->ToKey(roots, i, &k)) continue;
5955 array->set(array_size++, Smi::FromInt(i.as_int()));
5956 }
5957
5958 // The global dictionary doesn't track its deletion count, so we may iterate
5959 // fewer entries than the count of elements claimed by the dictionary.
5960 if (std::is_same_v<Derived, GlobalDictionary>) {
5961 DCHECK_LE(array_size, dictionary->NumberOfElements());
5962 } else {
5963 DCHECK_EQ(array_size, dictionary->NumberOfElements());
5964 }
5965
5966 EnumIndexComparator<Derived> cmp(raw_dictionary);
5967 // Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
5968 // store operations that are safe for concurrent marking.
5969 AtomicSlot start(array->RawFieldOfFirstElement());
5970 std::sort(start, start + array_size, cmp);
5971 }
5972 return FixedArray::RightTrimOrEmpty(isolate, array, array_size);
5973}
5974
5975// Backwards lookup (slow).
5976template <typename Derived, typename Shape>
5977Tagged<Object> Dictionary<Derived, Shape>::SlowReverseLookup(
5978 Tagged<Object> value) {
5979 Tagged<Derived> dictionary = Cast<Derived>(this);
5980 ReadOnlyRoots roots = GetReadOnlyRoots();
5981 for (InternalIndex i : dictionary->IterateEntries()) {
5983 if (!dictionary->ToKey(roots, i, &k)) continue;
5984 Tagged<Object> e = dictionary->ValueAt(i);
5985 if (e == value) return k;
5986 }
5987 return roots.undefined_value();
5988}
5989
5990template <typename Derived, typename Shape>
5991void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles(
5992 DirectHandle<Derived> table) {
5993 auto roots = GetReadOnlyRoots();
5994 int length = table->length();
5995 for (int i = Derived::EntryToIndex(InternalIndex(0)); i < length; i++) {
5996 table->set_the_hole(roots, i);
5997 }
5998}
5999
6000template <typename Derived, typename Shape>
6001Tagged<Object> ObjectHashTableBase<Derived, Shape>::Lookup(
6002 PtrComprCageBase cage_base, DirectHandle<Object> key, int32_t hash) {
6004 ReadOnlyRoots roots = GetReadOnlyRoots();
6005 DCHECK(this->IsKey(roots, *key));
6006
6007 InternalIndex entry = this->FindEntry(cage_base, roots, key, hash);
6008 if (entry.is_not_found()) return roots.the_hole_value();
6009 return this->get(Derived::EntryToIndex(entry) + 1);
6010}
6011
6012// The implementation should be in sync with
6013// CodeStubAssembler::NameToIndexHashTableLookup.
6016 PtrComprCageBase cage_base = GetPtrComprCageBase(this);
6018
6019 InternalIndex entry = this->FindEntry(cage_base, roots, key, key->hash());
6020 if (entry.is_not_found()) return -1;
6021 return Cast<Smi>(this->get(EntryToValueIndex(entry))).value();
6022}
6023
6024template <typename Derived, typename Shape>
6025Tagged<Object> ObjectHashTableBase<Derived, Shape>::Lookup(
6028
6029 PtrComprCageBase cage_base = GetPtrComprCageBase(this);
6031 DCHECK(this->IsKey(roots, *key));
6032
6033 // If the object does not have an identity hash, it was never used as a key.
6035 if (IsUndefined(hash, roots)) {
6036 return roots.the_hole_value();
6037 }
6038 return Lookup(cage_base, key, Smi::ToInt(hash));
6039}
6040
6041template <typename Derived, typename Shape>
6042Tagged<Object> ObjectHashTableBase<Derived, Shape>::Lookup(
6043 DirectHandle<Object> key, int32_t hash) {
6044 return Lookup(GetPtrComprCageBase(this), key, hash);
6045}
6046
6047template <typename Derived, typename Shape>
6048Tagged<Object> ObjectHashTableBase<Derived, Shape>::ValueAt(
6049 InternalIndex entry) {
6050 return this->get(EntryToValueIndex(entry));
6051}
6052
6054 return this->get(EntryToValueIndex(entry));
6055}
6056
6058 return this->get(EntryToValueIndex(entry));
6059}
6060
6062 Tagged<Object> value = ValueAt(entry);
6063 if (IsSmi(value)) {
6064 int index = Smi::ToInt(value);
6065 DCHECK_LE(0, index);
6066 return index;
6067 }
6068 return -1;
6069}
6070
6071template <typename Derived, typename Shape>
6072Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(
6074 DirectHandle<Object> value) {
6075 Isolate* isolate = Heap::FromWritableHeapObject(*table)->isolate();
6076 DCHECK(table->IsKey(ReadOnlyRoots(isolate), *key));
6077 DCHECK(!IsTheHole(*value, ReadOnlyRoots(isolate)));
6078
6079 // Make sure the key object has an identity hash code.
6080 int32_t hash = Object::GetOrCreateHash(*key, isolate).value();
6081
6082 return ObjectHashTableBase<Derived, Shape>::Put(isolate, table, key, value,
6083 hash);
6084}
6085
6086namespace {
6087
6088template <typename T, template <typename> typename HandleType>
6089void RehashObjectHashTableAndGCIfNeeded(Isolate* isolate, HandleType<T> table) {
6090 // Rehash if more than 33% of the entries are deleted entries.
6091 // TODO(verwaest): Consider to shrink the fixed array in place.
6092 if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
6093 table->Rehash(isolate);
6094 }
6095 // If we're out of luck, we didn't get a GC recently, and so rehashing
6096 // isn't enough to avoid a crash.
6097 if (!table->HasSufficientCapacityToAdd(1)) {
6098 int nof = table->NumberOfElements() + 1;
6099 int capacity = T::ComputeCapacity(nof);
6100 if (capacity > T::kMaxCapacity) {
6101 for (size_t i = 0; i < 2; ++i) {
6102 isolate->heap()->CollectAllGarbage(
6104 }
6105 table->Rehash(isolate);
6106 }
6107 }
6108}
6109
6110} // namespace
6111
6112template <typename Derived, typename Shape>
6113Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(
6114 Isolate* isolate, Handle<Derived> table, DirectHandle<Object> key,
6115 DirectHandle<Object> value, int32_t hash) {
6116 ReadOnlyRoots roots(isolate);
6117 DCHECK(table->IsKey(roots, *key));
6118 DCHECK(!IsTheHole(*value, roots));
6119
6120 InternalIndex entry = table->FindEntry(isolate, roots, key, hash);
6121
6122 // Key is already in table, just overwrite value.
6123 if (entry.is_found()) {
6124 table->set(Derived::EntryToValueIndex(entry), *value);
6125 return table;
6126 }
6127
6128 RehashObjectHashTableAndGCIfNeeded(isolate, table);
6129
6130 // Check whether the hash table should be extended.
6131 table = Derived::EnsureCapacity(isolate, table);
6132 table->AddEntry(table->FindInsertionEntry(isolate, hash), *key, *value);
6133 return table;
6134}
6135
6136template <typename Derived, typename Shape>
6137Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
6138 Isolate* isolate, Handle<Derived> table, DirectHandle<Object> key,
6139 bool* was_present) {
6140 DCHECK(table->IsKey(GetReadOnlyRoots(), *key));
6141
6143 if (IsUndefined(hash)) {
6144 *was_present = false;
6145 return table;
6146 }
6147
6148 return Remove(isolate, table, key, was_present, Smi::ToInt(hash));
6149}
6150
6151template <typename Derived, typename Shape>
6152Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
6153 Isolate* isolate, Handle<Derived> table, DirectHandle<Object> key,
6154 bool* was_present, int32_t hash) {
6155 ReadOnlyRoots roots = GetReadOnlyRoots();
6156 DCHECK(table->IsKey(roots, *key));
6157
6158 InternalIndex entry = table->FindEntry(isolate, roots, key, hash);
6159 if (entry.is_not_found()) {
6160 *was_present = false;
6161 return table;
6162 }
6163
6164 *was_present = true;
6165 table->RemoveEntry(entry);
6166 return Derived::Shrink(isolate, table);
6167}
6168
6169template <typename Derived, typename Shape>
6170void ObjectHashTableBase<Derived, Shape>::AddEntry(InternalIndex entry,
6172 Tagged<Object> value) {
6173 Derived* self = static_cast<Derived*>(this);
6174 self->set_key(Derived::EntryToIndex(entry), key);
6175 self->set(Derived::EntryToValueIndex(entry), value);
6176 self->ElementAdded();
6177}
6178
6179template <typename Derived, typename Shape>
6180void ObjectHashTableBase<Derived, Shape>::RemoveEntry(InternalIndex entry) {
6181 auto roots = GetReadOnlyRoots();
6182 this->set_the_hole(roots, Derived::EntryToIndex(entry));
6183 this->set_the_hole(roots, Derived::EntryToValueIndex(entry));
6184 this->ElementRemoved();
6185}
6186
6187template <typename Derived, int N>
6190 return Lookup(GetPtrComprCageBase(this), key);
6191}
6192
6193template <typename Derived, int N>
6197
6199 DCHECK(this->IsKey(roots, *key));
6200
6201 Tagged<Object> hash_obj = Object::GetHash(*key);
6202 if (IsUndefined(hash_obj, roots)) {
6203 return {roots.the_hole_value(), roots.the_hole_value()};
6204 }
6205 int32_t hash = Smi::ToInt(hash_obj);
6206
6207 InternalIndex entry = this->FindEntry(cage_base, roots, key, hash);
6208 if (entry.is_not_found()) {
6209 return {roots.the_hole_value(), roots.the_hole_value()};
6210 }
6211
6212 int start_index = this->EntryToIndex(entry) +
6214 std::array<Tagged<Object>, N> values;
6215 for (int i = 0; i < N; i++) {
6216 values[i] = this->get(start_index + i);
6217 DCHECK(!IsTheHole(values[i]));
6218 }
6219 return values;
6220}
6221
6222// static
6223template <typename Derived, int N>
6226 const std::array<DirectHandle<Object>, N>& values) {
6227 ReadOnlyRoots roots(isolate);
6228 DCHECK(table->IsKey(roots, *key));
6229
6230 int32_t hash = Object::GetOrCreateHash(*key, isolate).value();
6231 InternalIndex entry = table->FindEntry(isolate, roots, key, hash);
6232
6233 // Overwrite values if entry is found.
6234 if (entry.is_found()) {
6235 table->SetEntryValues(entry, values);
6236 return table;
6237 }
6238
6239 RehashObjectHashTableAndGCIfNeeded(isolate, table);
6240
6241 // Check whether the hash table should be extended.
6242 table = Derived::EnsureCapacity(isolate, table);
6243 entry = table->FindInsertionEntry(isolate, hash);
6244 table->set(Derived::EntryToIndex(entry), *key);
6245 table->SetEntryValues(entry, values);
6246 return table;
6247}
6248
6249template <typename Derived, int N>
6251 InternalIndex entry, const std::array<DirectHandle<Object>, N>& values) {
6252 int start_index = EntryToValueIndexStart(entry);
6253 for (int i = 0; i < N; i++) {
6254 this->set(start_index + i, *values[i]);
6255 }
6256}
6257
6261 int32_t hash = Object::GetOrCreateHash(*key, isolate).value();
6262 if (!set->Has(isolate, key, hash)) {
6263 set = EnsureCapacity(isolate, set);
6264 InternalIndex entry = set->FindInsertionEntry(isolate, hash);
6265 set->set(EntryToIndex(entry), *key);
6266 set->ElementAdded();
6267 }
6268 return set;
6269}
6270
6272 DirectHandle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
6273 set->set_table(*table);
6274}
6275
6277 Handle<OrderedHashSet> table(Cast<OrderedHashSet>(set->table()), isolate);
6278 table = OrderedHashSet::Clear(isolate, table);
6279 set->set_table(*table);
6280}
6281
6282void JSSet::Rehash(Isolate* isolate) {
6283 Handle<OrderedHashSet> table_handle(Cast<OrderedHashSet>(table()), isolate);
6285 OrderedHashSet::Rehash(isolate, table_handle).ToHandleChecked();
6286 set_table(*new_table);
6287}
6288
6290 DirectHandle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
6291 map->set_table(*table);
6292}
6293
6295 Handle<OrderedHashMap> table(Cast<OrderedHashMap>(map->table()), isolate);
6296 table = OrderedHashMap::Clear(isolate, table);
6297 map->set_table(*table);
6298}
6299
6300void JSMap::Rehash(Isolate* isolate) {
6301 Handle<OrderedHashMap> table_handle(Cast<OrderedHashMap>(table()), isolate);
6303 OrderedHashMap::Rehash(isolate, table_handle).ToHandleChecked();
6304 set_table(*new_table);
6305}
6306
6308 DirectHandle<JSWeakCollection> weak_collection, Isolate* isolate) {
6309 DirectHandle<EphemeronHashTable> table = EphemeronHashTable::New(isolate, 0);
6310 weak_collection->set_table(*table);
6311}
6312
6315 int32_t hash) {
6316 DCHECK(IsJSReceiver(*key) || IsSymbol(*key));
6318 Cast<EphemeronHashTable>(weak_collection->table()),
6319 weak_collection->GetIsolate());
6320 DCHECK(table->IsKey(GetReadOnlyRoots(), *key));
6321 DirectHandle<EphemeronHashTable> new_table = EphemeronHashTable::Put(
6322 weak_collection->GetIsolate(), table, key, value, hash);
6323 weak_collection->set_table(*new_table);
6324 if (*table != *new_table) {
6325 // Zap the old table since we didn't record slots for its elements.
6326 EphemeronHashTable::FillEntriesWithHoles(table);
6327 }
6328}
6329
6331 DirectHandle<Object> key, int32_t hash) {
6332 DCHECK(IsJSReceiver(*key) || IsSymbol(*key));
6334 Cast<EphemeronHashTable>(weak_collection->table()),
6335 weak_collection->GetIsolate());
6336 DCHECK(table->IsKey(GetReadOnlyRoots(), *key));
6337 bool was_present = false;
6338 DirectHandle<EphemeronHashTable> new_table = EphemeronHashTable::Remove(
6339 weak_collection->GetIsolate(), table, key, &was_present, hash);
6340 weak_collection->set_table(*new_table);
6341 if (*table != *new_table) {
6342 // Zap the old table since we didn't record slots for its elements.
6343 EphemeronHashTable::FillEntriesWithHoles(table);
6344 }
6345 return was_present;
6346}
6347
6349 DirectHandle<JSWeakCollection> holder, int max_entries) {
6350 Isolate* isolate = holder->GetIsolate();
6352 Cast<EphemeronHashTable>(holder->table()), isolate);
6353 if (max_entries == 0 || max_entries > table->NumberOfElements()) {
6354 max_entries = table->NumberOfElements();
6355 }
6356 int values_per_entry = IsJSWeakMap(*holder) ? 2 : 1;
6358 isolate->factory()->NewFixedArray(max_entries * values_per_entry);
6359 // Recompute max_values because GC could have removed elements from the table.
6360 if (max_entries > table->NumberOfElements()) {
6361 max_entries = table->NumberOfElements();
6362 }
6363
6364 {
6366 ReadOnlyRoots roots = ReadOnlyRoots(isolate);
6367 int count = 0;
6368 for (int i = 0;
6369 count / values_per_entry < max_entries && i < table->Capacity(); i++) {
6371 if (table->ToKey(roots, InternalIndex(i), &key)) {
6372 entries->set(count++, key);
6373 if (values_per_entry > 1) {
6374 Tagged<Object> value = table->Lookup(direct_handle(key, isolate));
6375 entries->set(count++, value);
6376 }
6377 }
6378 }
6379 DCHECK_EQ(max_entries * values_per_entry, count);
6380 }
6381 return isolate->factory()->NewJSArrayWithElements(entries);
6382}
6383
6385 Isolate* isolate, DirectHandle<JSDisposableStackBase> disposable_stack) {
6386 DirectHandle<FixedArray> array = isolate->factory()->NewFixedArray(0);
6387 disposable_stack->set_stack(*array);
6388 disposable_stack->set_needs_await(false);
6389 disposable_stack->set_has_awaited(false);
6390 disposable_stack->set_suppressed_error_created(false);
6391 disposable_stack->set_length(0);
6392 disposable_stack->set_state(DisposableStackState::kPending);
6393 disposable_stack->set_error(*(isolate->factory()->uninitialized_value()));
6394 disposable_stack->set_error_message(
6395 *(isolate->factory()->uninitialized_value()));
6396}
6397
6399 DCHECK(!IsPropertyCellHole(value(), isolate));
6400 PropertyDetails details = property_details();
6401 details = details.set_cell_type(PropertyCellType::kConstant);
6402 Transition(details, isolate->factory()->property_cell_hole_value());
6405}
6406
6407// static
6409 Isolate* isolate, DirectHandle<GlobalDictionary> dictionary,
6410 InternalIndex entry, PropertyDetails new_details,
6411 DirectHandle<Object> new_value) {
6412 DirectHandle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
6413 DirectHandle<Name> name(cell->name(), isolate);
6414 DCHECK(cell->property_details().IsConfigurable());
6415 DCHECK(!IsAnyHole(cell->value(), isolate));
6416
6417 // Swap with a new property cell.
6418 Handle<PropertyCell> new_cell =
6419 isolate->factory()->NewPropertyCell(name, new_details, new_value);
6420 dictionary->ValueAtPut(entry, *new_cell);
6421
6422 cell->ClearAndInvalidate(isolate);
6423 return new_cell;
6424}
6425
6427 Tagged<Object> value) {
6429 // TODO(dcarney): double->smi and smi->double transition from kConstant
6430 if (IsSmi(cell->value()) && IsSmi(value)) {
6431 return true;
6432 } else if (IsHeapObject(cell->value()) && IsHeapObject(value)) {
6433 Tagged<Map> map = Cast<HeapObject>(value)->map();
6434 return Cast<HeapObject>(cell->value())->map() == map && map->is_stable();
6435 }
6436 return false;
6437}
6438
6439// static
6441 Tagged<Object> value) {
6442 return IsUndefined(value, isolate) ? PropertyCellType::kUndefined
6444}
6445
6446// static
6449 Tagged<Object> value,
6450 PropertyDetails details) {
6452 DCHECK(!IsAnyHole(value, isolate));
6453 DCHECK(!IsAnyHole(cell->value(), isolate));
6454 switch (details.cell_type()) {
6458 if (value == cell->value()) return PropertyCellType::kConstant;
6459 [[fallthrough]];
6461 if (RemainsConstantType(cell, value)) {
6463 }
6464 [[fallthrough]];
6468 UNREACHABLE();
6469 }
6470 UNREACHABLE();
6471}
6472
6474 Isolate* isolate, DirectHandle<GlobalDictionary> dictionary,
6475 InternalIndex entry, DirectHandle<Object> value, PropertyDetails details) {
6476 DCHECK(!IsAnyHole(*value, isolate));
6477 Tagged<PropertyCell> raw_cell = dictionary->CellAt(entry);
6478 CHECK(!IsAnyHole(raw_cell->value(), isolate));
6479 const PropertyDetails original_details = raw_cell->property_details();
6480 // Data accesses could be cached in ics or optimized code.
6481 bool invalidate = original_details.kind() == PropertyKind::kData &&
6482 details.kind() == PropertyKind::kAccessor;
6483 int index = original_details.dictionary_index();
6484 DCHECK_LT(0, index);
6485 details = details.set_index(index);
6486
6487 PropertyCellType new_type =
6488 UpdatedType(isolate, raw_cell, *value, original_details);
6489 details = details.set_cell_type(new_type);
6490
6491 Handle<PropertyCell> cell(raw_cell, isolate);
6492
6493 if (invalidate) {
6494 cell = PropertyCell::InvalidateAndReplaceEntry(isolate, dictionary, entry,
6495 details, value);
6496 } else {
6497 cell->Transition(details, value);
6498 // Deopt when transitioning from a constant type or when making a writable
6499 // property read-only. Making a read-only property writable again is not
6500 // interesting because Turbofan does not currently rely on read-only unless
6501 // the property is also configurable, in which case it will stay read-only
6502 // forever.
6503 if (original_details.cell_type() != new_type ||
6504 (!original_details.IsReadOnly() && details.IsReadOnly())) {
6507 }
6508 }
6509 return cell;
6510}
6511
6512// static
6523
6524// static
6526 Tagged<Object> value) {
6528 PropertyCellType cell_type = details.cell_type();
6530 if (IsPropertyCellHole(value)) {
6532 } else {
6533 CHECK_EQ(IsAccessorInfo(value) || IsAccessorPair(value),
6534 details.kind() == PropertyKind::kAccessor);
6536 IsUndefined(value));
6537 }
6538 return true;
6539}
6540
6541#ifdef DEBUG
6542bool PropertyCell::CanTransitionTo(PropertyDetails new_details,
6543 Tagged<Object> new_value) const {
6544 // Extending the implementation of PropertyCells with additional states
6545 // and/or transitions likely requires changes to PropertyCellData::Serialize.
6547 DCHECK(CheckDataIsCompatible(new_details, new_value));
6548 switch (property_details().cell_type()) {
6550 return new_details.cell_type() != PropertyCellType::kUndefined;
6552 return !IsPropertyCellHole(value()) &&
6553 new_details.cell_type() != PropertyCellType::kUndefined;
6555 return new_details.cell_type() == PropertyCellType::kConstantType ||
6556 new_details.cell_type() == PropertyCellType::kMutable ||
6557 (new_details.cell_type() == PropertyCellType::kConstant &&
6558 IsPropertyCellHole(new_value));
6560 return new_details.cell_type() == PropertyCellType::kMutable ||
6561 (new_details.cell_type() == PropertyCellType::kConstant &&
6562 IsPropertyCellHole(new_value));
6564 UNREACHABLE();
6565 }
6566 UNREACHABLE();
6567}
6568#endif // DEBUG
6569
6571 DCHECK(IsSmi(input_or_debug_pos()));
6572 int code_offset = Smi::ToInt(input_or_debug_pos());
6573
6574 // The stored bytecode offset is relative to a different base than what
6575 // is used in the source position table, hence the subtraction.
6577 return code_offset;
6578}
6579
6581 CHECK(is_suspended());
6582 DCHECK(function()->shared()->HasBytecodeArray());
6583 Isolate* isolate = GetIsolate();
6584 DCHECK(function()
6585 ->shared()
6586 ->GetBytecodeArray(isolate)
6587 ->HasSourcePositionTable());
6588 Tagged<BytecodeArray> bytecode =
6589 function()->shared()->GetBytecodeArray(isolate);
6590 return bytecode->SourcePosition(code_offset());
6591}
6592
6593// static
6597 DCHECK(receiver->map()->is_access_check_needed());
6598 Tagged<Object> maybe_constructor = receiver->map()->GetConstructor();
6599 if (IsFunctionTemplateInfo(maybe_constructor)) {
6600 Tagged<Object> data_obj =
6601 Cast<FunctionTemplateInfo>(maybe_constructor)->GetAccessCheckInfo();
6602 if (IsUndefined(data_obj, isolate)) return AccessCheckInfo();
6603 return Cast<AccessCheckInfo>(data_obj);
6604 }
6605 // Might happen for a detached context.
6606 if (!IsJSFunction(maybe_constructor)) return AccessCheckInfo();
6607 Tagged<JSFunction> constructor = Cast<JSFunction>(maybe_constructor);
6608 // Might happen for the debug context.
6609 if (!constructor->shared()->IsApiFunction()) return AccessCheckInfo();
6610
6611 Tagged<Object> data_obj =
6612 constructor->shared()->api_func_data()->GetAccessCheckInfo();
6613 if (IsUndefined(data_obj, isolate)) return AccessCheckInfo();
6614
6615 return Cast<AccessCheckInfo>(data_obj);
6616}
6617
6619 Tagged<Smi> y) {
6621 DisallowJavascriptExecution no_js(isolate);
6622
6623 int x_value = Smi::ToInt(x);
6624 int y_value = Smi::ToInt(y);
6625
6626 // If the integers are equal so are the string representations.
6627 if (x_value == y_value) return Smi::FromInt(0).ptr();
6628
6629 // If one of the integers is zero the normal integer order is the
6630 // same as the lexicographic order of the string representations.
6631 if (x_value == 0 || y_value == 0) {
6632 return Smi::FromInt(x_value < y_value ? -1 : 1).ptr();
6633 }
6634
6635 // If only one of the integers is negative the negative number is
6636 // smallest because the char code of '-' is less than the char code
6637 // of any digit. Otherwise, we make both values positive.
6638
6639 // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
6640 // architectures using 32-bit Smis.
6641 uint32_t x_scaled = x_value;
6642 uint32_t y_scaled = y_value;
6643 if (x_value < 0) {
6644 if (y_value >= 0) {
6645 return Smi::FromInt(-1).ptr();
6646 } else {
6647 y_scaled = base::NegateWithWraparound(y_value);
6648 }
6649 x_scaled = base::NegateWithWraparound(x_value);
6650 } else if (y_value < 0) {
6651 return Smi::FromInt(1).ptr();
6652 }
6653
6654 // clang-format off
6655 static const uint32_t kPowersOf10[] = {
6656 1, 10, 100, 1000,
6657 10 * 1000, 100 * 1000, 1000 * 1000, 10 * 1000 * 1000,
6658 100 * 1000 * 1000, 1000 * 1000 * 1000};
6659 // clang-format on
6660
6661 // If the integers have the same number of decimal digits they can be
6662 // compared directly as the numeric order is the same as the
6663 // lexicographic order. If one integer has fewer digits, it is scaled
6664 // by some power of 10 to have the same number of digits as the longer
6665 // integer. If the scaled integers are equal it means the shorter
6666 // integer comes first in the lexicographic order.
6667
6668 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6669 int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled);
6670 int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6671 x_log10 -= x_scaled < kPowersOf10[x_log10];
6672
6673 int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled);
6674 int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6675 y_log10 -= y_scaled < kPowersOf10[y_log10];
6676
6677 int tie = 0;
6678
6679 if (x_log10 < y_log10) {
6680 // X has fewer digits. We would like to simply scale up X but that
6681 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6682 // be scaled up to 9_000_000_000. So we scale up by the next
6683 // smallest power and scale down Y to drop one digit. It is OK to
6684 // drop one digit from the longer integer since the final digit is
6685 // past the length of the shorter integer.
6686 x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
6687 y_scaled /= 10;
6688 tie = -1;
6689 } else if (y_log10 < x_log10) {
6690 y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
6691 x_scaled /= 10;
6692 tie = 1;
6693 }
6694
6695 if (x_scaled < y_scaled) return Smi::FromInt(-1).ptr();
6696 if (x_scaled > y_scaled) return Smi::FromInt(1).ptr();
6697 return Smi::FromInt(tie).ptr();
6698}
6699
6700// static
6702 MapWord map_word = map->map_word(kRelaxedLoad);
6703 if (map_word.IsForwardingAddress()) {
6704 // During GC we can't access forwarded maps without synchronization.
6705 return true;
6706 }
6707 // The meta map might be moved away by GC too but we can read instance
6708 // type from both old and new location as it can't change.
6709 return InstanceTypeChecker::IsMap(map_word.ToMap()->instance_type());
6710}
6711
6712// Force instantiation of template instances class.
6713// Please note this list is compiler dependent.
6714// Keep this at the end of this file
6715
6716#define EXTERN_DEFINE_HASH_TABLE(DERIVED, SHAPE) \
6717 template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) \
6718 HashTable<DERIVED, SHAPE>; \
6719 \
6720 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
6721 HashTable<DERIVED, SHAPE>::New(Isolate*, int, AllocationType, \
6722 MinimumCapacity); \
6723 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
6724 HashTable<DERIVED, SHAPE>::New(LocalIsolate*, int, AllocationType, \
6725 MinimumCapacity); \
6726 \
6727 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
6728 HashTable<DERIVED, SHAPE>::EnsureCapacity(Isolate*, Handle<DERIVED>, int, \
6729 AllocationType); \
6730 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
6731 HashTable<DERIVED, SHAPE>::EnsureCapacity(LocalIsolate*, Handle<DERIVED>, \
6732 int, AllocationType); \
6733 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) DirectHandle<DERIVED> \
6734 HashTable<DERIVED, SHAPE>::EnsureCapacity(Isolate*, DirectHandle<DERIVED>, \
6735 int, AllocationType); \
6736 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) DirectHandle<DERIVED> \
6737 HashTable<DERIVED, SHAPE>::EnsureCapacity( \
6738 LocalIsolate*, DirectHandle<DERIVED>, int, AllocationType); \
6739 \
6740 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
6741 HashTable<DERIVED, SHAPE>::Shrink(Isolate*, Handle<DERIVED>, int); \
6742 template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) DirectHandle<DERIVED> \
6743 HashTable<DERIVED, SHAPE>::Shrink(Isolate*, DirectHandle<DERIVED>, int);
6744
6745#define EXTERN_DEFINE_OBJECT_BASE_HASH_TABLE(DERIVED, SHAPE) \
6746 EXTERN_DEFINE_HASH_TABLE(DERIVED, SHAPE) \
6747 template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) \
6748 ObjectHashTableBase<DERIVED, SHAPE>;
6749
6750#define EXTERN_DEFINE_MULTI_OBJECT_BASE_HASH_TABLE(DERIVED, N) \
6751 EXTERN_DEFINE_HASH_TABLE(DERIVED, ObjectMultiHashTableShape<N>) \
6752 template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) \
6753 ObjectMultiHashTableBase<DERIVED, N>;
6754
6755#define EXTERN_DEFINE_DICTIONARY(DERIVED, SHAPE) \
6756 EXTERN_DEFINE_HASH_TABLE(DERIVED, SHAPE) \
6757 template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) \
6758 Dictionary<DERIVED, SHAPE>; \
6759 \
6760 template V8_EXPORT_PRIVATE DirectHandle<DERIVED> \
6761 Dictionary<DERIVED, SHAPE>::Add(Isolate* isolate, DirectHandle<DERIVED>, \
6762 Key, DirectHandle<Object>, PropertyDetails, \
6763 InternalIndex*); \
6764 template V8_EXPORT_PRIVATE DirectHandle<DERIVED> \
6765 Dictionary<DERIVED, SHAPE>::Add( \
6766 LocalIsolate* isolate, DirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6767 PropertyDetails, InternalIndex*); \
6768 template V8_EXPORT_PRIVATE IndirectHandle<DERIVED> \
6769 Dictionary<DERIVED, SHAPE>::Add(Isolate* isolate, IndirectHandle<DERIVED>, \
6770 Key, DirectHandle<Object>, PropertyDetails, \
6771 InternalIndex*); \
6772 template V8_EXPORT_PRIVATE IndirectHandle<DERIVED> \
6773 Dictionary<DERIVED, SHAPE>::Add( \
6774 LocalIsolate* isolate, IndirectHandle<DERIVED>, Key, \
6775 DirectHandle<Object>, PropertyDetails, InternalIndex*); \
6776 template V8_EXPORT_PRIVATE DirectHandle<DERIVED> \
6777 Dictionary<DERIVED, SHAPE>::DeleteEntry( \
6778 Isolate* isolate, DirectHandle<DERIVED>, InternalIndex); \
6779 template V8_EXPORT_PRIVATE IndirectHandle<DERIVED> \
6780 Dictionary<DERIVED, SHAPE>::DeleteEntry( \
6781 Isolate* isolate, IndirectHandle<DERIVED>, InternalIndex); \
6782 template V8_EXPORT_PRIVATE DirectHandle<DERIVED> \
6783 Dictionary<DERIVED, SHAPE>::Shrink(Isolate* isolate, DirectHandle<DERIVED>); \
6784 template V8_EXPORT_PRIVATE IndirectHandle<DERIVED> \
6785 Dictionary<DERIVED, SHAPE>::Shrink(Isolate* isolate, \
6786 IndirectHandle<DERIVED>);
6787
6788#define EXTERN_DEFINE_BASE_NAME_DICTIONARY(DERIVED, SHAPE) \
6789 EXTERN_DEFINE_DICTIONARY(DERIVED, SHAPE) \
6790 template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) \
6791 BaseNameDictionary<DERIVED, SHAPE>; \
6792 \
6793 template V8_EXPORT_PRIVATE Handle<DERIVED> \
6794 BaseNameDictionary<DERIVED, SHAPE>::New(Isolate*, int, AllocationType, \
6795 MinimumCapacity); \
6796 template V8_EXPORT_PRIVATE Handle<DERIVED> \
6797 BaseNameDictionary<DERIVED, SHAPE>::New(LocalIsolate*, int, AllocationType, \
6798 MinimumCapacity); \
6799 \
6800 template V8_EXPORT_PRIVATE DirectHandle<DERIVED> \
6801 BaseNameDictionary<DERIVED, SHAPE>::Add( \
6802 Isolate* isolate, DirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6803 PropertyDetails, InternalIndex*); \
6804 template V8_EXPORT_PRIVATE IndirectHandle<DERIVED> \
6805 BaseNameDictionary<DERIVED, SHAPE>::Add( \
6806 Isolate* isolate, IndirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6807 PropertyDetails, InternalIndex*); \
6808 \
6809 template DirectHandle<DERIVED> \
6810 BaseNameDictionary<DERIVED, SHAPE>::AddNoUpdateNextEnumerationIndex( \
6811 Isolate* isolate, DirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6812 PropertyDetails, InternalIndex*); \
6813 template DirectHandle<DERIVED> \
6814 BaseNameDictionary<DERIVED, SHAPE>::AddNoUpdateNextEnumerationIndex( \
6815 LocalIsolate* isolate, DirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6816 PropertyDetails, InternalIndex*); \
6817 template IndirectHandle<DERIVED> \
6818 BaseNameDictionary<DERIVED, SHAPE>::AddNoUpdateNextEnumerationIndex( \
6819 Isolate* isolate, IndirectHandle<DERIVED>, Key, DirectHandle<Object>, \
6820 PropertyDetails, InternalIndex*); \
6821 template IndirectHandle<DERIVED> \
6822 BaseNameDictionary<DERIVED, SHAPE>::AddNoUpdateNextEnumerationIndex( \
6823 LocalIsolate* isolate, IndirectHandle<DERIVED>, Key, \
6824 DirectHandle<Object>, PropertyDetails, InternalIndex*);
6825
6826EXTERN_DEFINE_HASH_TABLE(StringSet, StringSetShape)
6827EXTERN_DEFINE_HASH_TABLE(CompilationCacheTable, CompilationCacheShape)
6828EXTERN_DEFINE_HASH_TABLE(ObjectHashSet, ObjectHashSetShape)
6829EXTERN_DEFINE_HASH_TABLE(NameToIndexHashTable, NameToIndexShape)
6830EXTERN_DEFINE_HASH_TABLE(RegisteredSymbolTable, RegisteredSymbolTableShape)
6831
6832EXTERN_DEFINE_OBJECT_BASE_HASH_TABLE(ObjectHashTable, ObjectHashTableShape)
6835
6837
6840
6841template V8_EXPORT_PRIVATE void
6842Dictionary<NumberDictionary, NumberDictionaryShape>::UncheckedAdd<
6845 uint32_t, DirectHandle<Object>,
6847template V8_EXPORT_PRIVATE void
6848Dictionary<NumberDictionary, NumberDictionaryShape>::UncheckedAdd<
6852
6858
6860
6861#undef EXTERN_DEFINE_HASH_TABLE
6862#undef EXTERN_DEFINE_OBJECT_BASE_HASH_TABLE
6863#undef EXTERN_DEFINE_DICTIONARY
6864#undef EXTERN_DEFINE_BASE_NAME_DICTIONARY
6865
6866} // namespace v8::internal
ThreadLocalTop * top
Builtins::Kind kind
Definition builtins.cc:40
PropertyT * getter
#define SLOW_DCHECK(condition)
Definition checks.h:21
SourcePosition pos
@ kAttemptOverrideReadOnlyOnPrototypeSloppy
Definition v8-isolate.h:538
@ kAttemptOverrideReadOnlyOnPrototypeStrict
Definition v8-isolate.h:539
V8_WARN_UNUSED_RESULT V8_INLINE bool To(T *out) const
Definition v8-maybe.h:55
V8_INLINE bool IsJust() const
Definition v8-maybe.h:36
V8_INLINE T FromJust() const &
Definition v8-maybe.h:64
V8_INLINE bool IsNothing() const
Definition v8-maybe.h:35
uint32_t GetHash()
Definition api.cc:4282
static constexpr int kSize
Definition bit-field.h:40
static Tagged< AccessCheckInfo > Get(Isolate *isolate, DirectHandle< JSObject > receiver)
Definition objects.cc:6594
static int AppendUnique(Isolate *isolate, DirectHandle< Object > descriptors, DirectHandle< FixedArray > array, int valid_descriptors)
Definition objects.cc:2841
static Handle< JSAny > GetComponent(Isolate *isolate, DirectHandle< NativeContext > native_context, DirectHandle< AccessorPair > accessor_pair, AccessorComponent component)
Definition objects.cc:4015
static NEVER_READ_ONLY_SPACE DirectHandle< AccessorPair > Copy(Isolate *isolate, DirectHandle< AccessorPair > pair)
Definition objects.cc:4004
static MaybeDirectHandle< Object > ReplaceAccessorWithDataProperty(Isolate *isolate, DirectHandle< JSAny > receiver, DirectHandle< JSObject > holder, DirectHandle< Name > name, DirectHandle< Object > value)
Definition accessors.cc:88
const char * PretenureDecisionName(PretenureDecision decision)
Definition objects.cc:4931
static bool ShouldTrack(ElementsKind boilerplate_elements_kind)
AllocationType GetAllocationType() const
Definition objects.cc:4906
static V8_WARN_UNUSED_RESULT MaybeHandle< JSFunction > InstantiateFunction(Isolate *isolate, DirectHandle< NativeContext > native_context, DirectHandle< FunctionTemplateInfo > data, MaybeDirectHandle< Name > maybe_name={})
static Maybe< ComparisonResult > CompareToString(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< String > y)
Definition bigint.cc:625
static Maybe< bool > EqualToString(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< String > y)
Definition bigint.cc:643
static ComparisonResult CompareToBigInt(DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:579
static uint32_t SizeFor(uint32_t length)
Definition bigint.h:252
static MaybeHandle< String > ToString(Isolate *isolate, DirectHandle< BigInt > bigint, int radix=10, ShouldThrow should_throw=kThrowOnError)
Definition bigint.cc:835
static bool EqualToBigInt(Tagged< BigInt > x, Tagged< BigInt > y)
Definition bigint.cc:590
static bool EqualToNumber(DirectHandle< BigInt > x, DirectHandle< Object > y)
Definition bigint.cc:660
static DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< BigInt > bigint)
Definition bigint.cc:922
static ComparisonResult CompareToNumber(DirectHandle< BigInt > x, DirectHandle< Object > y)
Definition bigint.cc:679
static void IteratePointers(Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > InvokeApiFunction(Isolate *isolate, bool is_construct, DirectHandle< FunctionTemplateInfo > function, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args, DirectHandle< HeapObject > new_target)
static constexpr int SizeFor(int length)
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1931
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1927
static V8_INLINE constexpr int SizeFor(int length)
Definition contexts.h:503
static int SizeFor(int slot_count)
static void DeoptimizeDependencyGroups(Isolate *isolate, ObjectT object, DependencyGroups groups)
PropertyDetails GetDetails(InternalIndex descriptor_number)
bool IsEqualUpTo(Tagged< DescriptorArray > desc, int nof_descriptors)
Definition objects.cc:3757
void Replace(InternalIndex descriptor_number, Descriptor *descriptor)
Definition objects.cc:3908
void CopyFrom(InternalIndex index, Tagged< DescriptorArray > src)
Definition objects.cc:3929
void Set(InternalIndex descriptor_number, Descriptor *desc)
static void InitializeOrChangeEnumCache(DirectHandle< DescriptorArray > descriptors, Isolate *isolate, DirectHandle< FixedArray > keys, DirectHandle< FixedArray > indices, AllocationType allocation_if_initialize)
Definition objects.cc:3914
int GetSortedKeyIndex(int descriptor_number)
static DirectHandle< DescriptorArray > CopyUpToAddAttributes(Isolate *isolate, DirectHandle< DescriptorArray > desc, int enumeration_index, PropertyAttributes attributes, int slack=0)
Definition objects.cc:3711
ObjectSlot GetDescriptorSlot(int descriptor)
void Initialize(Tagged< EnumCache > enum_cache, Tagged< HeapObject > undefined_value, int nof_descriptors, int slack, uint32_t raw_gc_state)
Definition objects.cc:3889
Tagged< Name > GetKey(InternalIndex descriptor_number) const
V8_EXPORT_PRIVATE void Sort()
Definition objects.cc:3935
void SetSortedKey(int pointer, int descriptor_number)
static V8_EXPORT_PRIVATE Handle< DescriptorArray > Allocate(IsolateT *isolate, int nof_descriptors, int slack, AllocationType allocation=AllocationType::kYoung)
Tagged< MaybeObject > GetValue(InternalIndex descriptor_number)
static constexpr int SizeFor(int number_of_all_descriptors)
void SwapSortedKeys(int first, int second)
void SetDetails(InternalIndex descriptor_number, PropertyDetails details)
void GeneralizeAllFields(bool clear_constness)
Definition objects.cc:2238
Tagged< Name > GetSortedKey(int descriptor_number)
V8_EXPORT_PRIVATE void CheckNameCollisionDuringInsertion(Descriptor *desc, uint32_t descriptor_hash, int insertion_index)
Definition objects.cc:3989
static DirectHandle< DescriptorArray > CopyUpTo(Isolate *isolate, DirectHandle< DescriptorArray > desc, int enumeration_index, int slack=0)
Definition objects.cc:3704
void SetValue(InternalIndex descriptor_number, Tagged< MaybeObject > value)
void SetSortedKeyIndex(int index)
Definition property.h:33
V8_INLINE bool is_null() const
Definition handles.h:693
V8_INLINE bool is_identical_to(Handle< S > other) const
Definition handles.h:716
static constexpr int SizeFor(int length)
static bool HasErrorStackSymbolOwnProperty(Isolate *isolate, DirectHandle< JSObject > object)
Definition messages.cc:1118
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > Call(Isolate *isolate, DirectHandle< Object > callable, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args)
Definition execution.cc:523
Handle< Boolean > ToBoolean(bool value)
Isolate * isolate() const
Definition factory.h:1281
static V8_EXPORT_PRIVATE Tagged< FieldType > Class(Tagged< Map > map)
Definition field-type.cc:37
static V8_EXPORT_PRIVATE Tagged< FieldType > Any()
Definition field-type.cc:22
static V8_EXPORT_PRIVATE Tagged< FieldType > None()
Definition field-type.cc:17
static constexpr int kMaxLength
static HandleType< FixedArray > RightTrimOrEmpty(Isolate *isolate, HandleType< FixedArray > array, int new_length)
int function_literal_id() const
Definition ast.h:2408
Handle< SharedFunctionInfo > shared_function_info() const
Definition ast.h:2356
void set_shared_function_info(Handle< SharedFunctionInfo > shared_function_info)
Definition ast.cc:202
std::optional< Tagged< PropertyCell > > TryFindPropertyCellForConcurrentLookupIterator(Isolate *isolate, DirectHandle< Name > name, RelaxedLoadTag tag)
Definition objects.cc:5586
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
V8_EXPORT_PRIVATE int SizeFromMap(Tagged< Map > map) const
Definition objects.cc:1935
static constexpr int kHeaderSize
bool CanBeRehashed(PtrComprCageBase cage_base) const
Definition objects.cc:2129
V8_EXPORT_PRIVATE int SizeFromMap(Tagged< Map > map) const
Definition objects.cc:1939
bool NeedsRehashing(InstanceType instance_type) const
Definition objects.cc:2091
void RehashBasedOnMap(IsolateT *isolate)
Definition objects.cc:2166
MaybeDirectHandle< String > Finish()
V8_INLINE void AppendCharacter(uint8_t c)
V8_INLINE void AppendString(std::string_view str)
V8_INLINE void AppendCStringLiteral(const char(&literal)[N])
bool SetLengthWouldNormalize(uint32_t new_length)
Definition objects.cc:4891
static bool AnythingToArrayLength(Isolate *isolate, DirectHandle< Object > length_object, uint32_t *output)
Definition objects.cc:3188
static V8_EXPORT_PRIVATE Maybe< bool > SetLength(DirectHandle< JSArray > array, uint32_t length)
Definition objects.cc:4812
static V8_EXPORT_PRIVATE void Initialize(DirectHandle< JSArray > array, int capacity, int length=0)
Definition objects.cc:4804
static bool MayHaveReadOnlyLength(Tagged< Map > js_array_map)
Definition objects.cc:4949
static bool WouldChangeReadOnlyLength(DirectHandle< JSArray > array, uint32_t index)
Definition objects.cc:4976
static Address ArrayJoinConcatToSequentialString(Isolate *isolate, Address raw_fixed_array, intptr_t length, Address raw_separator, Address raw_dest)
Definition objects.cc:4246
static bool HasReadOnlyLength(DirectHandle< JSArray > array)
Definition objects.cc:4962
static V8_WARN_UNUSED_RESULT Maybe< bool > ArraySetLength(Isolate *isolate, DirectHandle< JSArray > a, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
Definition objects.cc:3224
static V8_WARN_UNUSED_RESULT Maybe< bool > DefineOwnProperty(Isolate *isolate, DirectHandle< JSArray > o, DirectHandle< Object > name, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
Definition objects.cc:3120
static MaybeHandle< String > GetName(Isolate *isolate, DirectHandle< JSBoundFunction > function)
static DirectHandle< String > ToString(DirectHandle< JSBoundFunction > function)
static void InitializeJSDisposableStackBase(Isolate *isolate, DirectHandle< JSDisposableStackBase > stack)
Definition objects.cc:6384
static Handle< String > GetName(Isolate *isolate, DirectHandle< JSFunction > function)
static DirectHandle< String > ToString(DirectHandle< JSFunction > function)
void Rehash(Isolate *isolate)
Definition objects.cc:6300
static void Clear(Isolate *isolate, DirectHandle< JSMap > map)
Definition objects.cc:6294
static void Initialize(DirectHandle< JSMap > map, Isolate *isolate)
Definition objects.cc:6289
static V8_EXPORT_PRIVATE DirectHandle< NumberDictionary > NormalizeElements(DirectHandle< JSObject > object)
static bool PrototypeHasNoElements(Isolate *isolate, Tagged< JSObject > object)
static V8_WARN_UNUSED_RESULT MaybeHandle< JSAny > GetPropertyWithInterceptor(LookupIterator *it, bool *done)
static V8_WARN_UNUSED_RESULT Maybe< InterceptorResult > SetPropertyWithInterceptor(LookupIterator *it, Maybe< ShouldThrow > should_throw, DirectHandle< Object > value)
static void ValidateElements(Tagged< JSObject > object)
static V8_WARN_UNUSED_RESULT Maybe< PropertyAttributes > GetPropertyAttributesWithInterceptor(LookupIterator *it)
static V8_EXPORT_PRIVATE Maybe< bool > AddDataElement(DirectHandle< JSObject > receiver, uint32_t index, DirectHandle< Object > value, PropertyAttributes attributes)
static V8_WARN_UNUSED_RESULT MaybeHandle< JSAny > GetPropertyWithFailedAccessCheck(LookupIterator *it)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetPropertyWithFailedAccessCheck(LookupIterator *it, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
static const char * Status(Promise::PromiseState status)
Definition objects.cc:5005
static Handle< Object > Reject(DirectHandle< JSPromise > promise, DirectHandle< Object > reason, bool debug_event=true)
Definition objects.cc:5069
void set_status(Promise::PromiseState status)
Definition objects.cc:4999
static Handle< Object > TriggerPromiseReactions(Isolate *isolate, DirectHandle< Object > reactions, DirectHandle< Object > argument, PromiseReaction::Type type)
Definition objects.cc:5205
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > Resolve(DirectHandle< JSPromise > promise, DirectHandle< Object > resolution)
Definition objects.cc:5109
static V8_EXPORT_PRIVATE Handle< Object > Fulfill(DirectHandle< JSPromise > promise, DirectHandle< Object > value)
Definition objects.cc:5018
V8_EXPORT_PRIVATE Promise::PromiseState status() const
Definition objects.cc:4993
static V8_WARN_UNUSED_RESULT Maybe< bool > HasProperty(Isolate *isolate, DirectHandle< JSProxy > proxy, DirectHandle< Name > name)
Definition objects.cc:2885
static V8_WARN_UNUSED_RESULT Maybe< bool > IsArray(DirectHandle< JSProxy > proxy)
Definition objects.cc:2864
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSProxy > New(Isolate *isolate, DirectHandle< Object >, DirectHandle< Object >)
Definition objects.cc:3083
static V8_WARN_UNUSED_RESULT MaybeHandle< JSAny > GetProperty(Isolate *isolate, DirectHandle< JSProxy > proxy, DirectHandle< Name > name, DirectHandle< JSAny > receiver, bool *was_found)
Definition objects.cc:1326
static void Revoke(DirectHandle< JSProxy > proxy)
Definition objects.cc:2851
static Maybe< bool > SetPrivateSymbol(Isolate *isolate, DirectHandle< JSProxy > proxy, DirectHandle< Symbol > private_name, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
Definition objects.cc:3443
static V8_WARN_UNUSED_RESULT Maybe< bool > SetProperty(DirectHandle< JSProxy > proxy, DirectHandle< Name > name, DirectHandle< Object > value, DirectHandle< JSAny > receiver, Maybe< ShouldThrow > should_throw)
Definition objects.cc:2958
static MaybeHandle< JSAny > CheckGetSetTrapResult(Isolate *isolate, DirectHandle< Name > name, DirectHandle< JSReceiver > target, DirectHandle< Object > trap_result, AccessKind access_kind)
Definition objects.cc:1379
static const int kMaxIterationLimit
Definition js-proxy.h:104
static V8_WARN_UNUSED_RESULT Maybe< bool > GetOwnPropertyDescriptor(Isolate *isolate, DirectHandle< JSProxy > proxy, DirectHandle< Name > name, PropertyDescriptor *desc)
Definition objects.cc:3490
static V8_WARN_UNUSED_RESULT Maybe< bool > SetPrototype(Isolate *isolate, DirectHandle< JSProxy > proxy, DirectHandle< Object > value, bool from_javascript, ShouldThrow should_throw)
Definition objects.cc:4822
static V8_WARN_UNUSED_RESULT Maybe< bool > IsExtensible(DirectHandle< JSProxy > proxy)
Definition objects.cc:3663
static V8_WARN_UNUSED_RESULT Maybe< bool > DeletePropertyOrElement(DirectHandle< JSProxy > proxy, DirectHandle< Name > name, LanguageMode language_mode)
Definition objects.cc:3010
static V8_WARN_UNUSED_RESULT Maybe< bool > CheckHasTrap(Isolate *isolate, DirectHandle< Name > name, DirectHandle< JSReceiver > target)
Definition objects.cc:2929
static V8_WARN_UNUSED_RESULT Maybe< bool > PreventExtensions(DirectHandle< JSProxy > proxy, ShouldThrow should_throw)
Definition objects.cc:3617
static V8_WARN_UNUSED_RESULT Maybe< bool > CheckDeleteTrap(Isolate *isolate, DirectHandle< Name > name, DirectHandle< JSReceiver > target)
Definition objects.cc:3054
static V8_WARN_UNUSED_RESULT Maybe< PropertyAttributes > GetPropertyAttributes(LookupIterator *it)
Definition objects.cc:3096
static V8_WARN_UNUSED_RESULT Maybe< bool > DefineOwnProperty(Isolate *isolate, DirectHandle< JSProxy > object, DirectHandle< Object > key, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
Definition objects.cc:3317
static MaybeDirectHandle< JSPrototype > GetPrototype(DirectHandle< JSProxy > receiver)
Definition objects.cc:1456
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > GetOwnPropertyDescriptor(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > key, PropertyDescriptor *desc)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > DeletePropertyOrElement(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name, LanguageMode language_mode=LanguageMode::kSloppy)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > SetPrototype(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > value, bool from_javascript, ShouldThrow should_throw)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetElement(Isolate *isolate, DirectHandle< JSReceiver > receiver, uint32_t index)
static MaybeDirectHandle< NativeContext > GetFunctionRealm(DirectHandle< JSReceiver > receiver)
static V8_WARN_UNUSED_RESULT Maybe< bool > PreventExtensions(Isolate *isolate, DirectHandle< JSReceiver > object, ShouldThrow should_throw)
static V8_WARN_UNUSED_RESULT Maybe< bool > HasInPrototypeChain(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > proto)
static V8_WARN_UNUSED_RESULT HandleType< Object >::MaybeType ToPrimitive(Isolate *isolate, HandleType< JSReceiver > receiver, ToPrimitiveHint hint=ToPrimitiveHint::kDefault)
static MaybeDirectHandle< JSPrototype > GetPrototype(Isolate *isolate, DirectHandle< JSReceiver > receiver)
static V8_WARN_UNUSED_RESULT Maybe< bool > CreateDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > key, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
static V8_WARN_UNUSED_RESULT Maybe< bool > IsExtensible(Isolate *isolate, DirectHandle< JSReceiver > object)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(Isolate *isolate, DirectHandle< JSReceiver > receiver, const char *key)
static V8_WARN_UNUSED_RESULT Maybe< bool > DefineOwnProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > key, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
static V8_EXPORT_PRIVATE MaybeHandle< NativeContext > GetContextForMicrotask(DirectHandle< JSReceiver > receiver)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > HasProperty(LookupIterator *it)
Definition js-objects.cc:98
void Rehash(Isolate *isolate)
Definition objects.cc:6282
static void Clear(Isolate *isolate, DirectHandle< JSSet > set)
Definition objects.cc:6276
static void Initialize(DirectHandle< JSSet > set, Isolate *isolate)
Definition objects.cc:6271
static bool Delete(DirectHandle< JSWeakCollection > collection, DirectHandle< Object > key, int32_t hash)
Definition objects.cc:6330
static DirectHandle< JSArray > GetEntries(DirectHandle< JSWeakCollection > holder, int max_entries)
Definition objects.cc:6348
static V8_EXPORT_PRIVATE void Set(DirectHandle< JSWeakCollection > collection, DirectHandle< Object > key, DirectHandle< Object > value, int32_t hash)
Definition objects.cc:6313
static void Initialize(DirectHandle< JSWeakCollection > collection, Isolate *isolate)
Definition objects.cc:6307
static DirectHandle< String > ToString(DirectHandle< JSWrappedFunction > function)
virtual void GetFunctions(std::vector< Tagged< SharedFunctionInfo > > *functions) const
Definition frames.cc:2436
DirectHandle< Object > GetAccessors() const
Definition lookup.cc:1064
Tagged< Map > ToMap() const
bool IsForwardingAddress() const
static V8_EXPORT_PRIVATE bool IsMapOrForwarded(Tagged< Map > map)
Definition objects.cc:6701
static const int kNoConstructorFunctionIndex
Definition map.h:257
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
V8_INLINE bool is_null() const
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1923
static V8_WARN_UNUSED_RESULT Handle< NameDictionary > New(IsolateT *isolate, int at_least_space_for, AllocationType allocation=AllocationType::kYoung, MinimumCapacity capacity_option=USE_DEFAULT_MINIMUM_CAPACITY)
int Lookup(DirectHandle< Name > key)
Definition objects.cc:6014
int IndexAt(InternalIndex entry)
Definition objects.cc:6061
Tagged< Object > ValueAt(InternalIndex entry)
Definition objects.cc:6057
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToFunctionName(Isolate *isolate, DirectHandle< Name > name)
Definition objects.cc:4049
void UpdateMaxNumberKey(uint32_t key, DirectHandle< JSObject > dictionary_holder)
Definition objects.cc:5858
static void UncheckedSet(Isolate *isolate, DirectHandle< NumberDictionary > dictionary, uint32_t key, DirectHandle< Object > value)
Definition objects.cc:5907
static V8_WARN_UNUSED_RESULT HandleType< NumberDictionary > Set(Isolate *isolate, HandleType< NumberDictionary > dictionary, uint32_t key, DirectHandle< Object > value, DirectHandle< JSObject > dictionary_holder=DirectHandle< JSObject >::null(), PropertyDetails details=PropertyDetails::Empty())
void CopyValuesTo(Tagged< FixedArray > elements)
Definition objects.cc:5913
static Handle< ObjectHashSet > Add(Isolate *isolate, Handle< ObjectHashSet > set, DirectHandle< Object > key)
Definition objects.cc:6258
void SetEntryValues(InternalIndex entry, const std::array< DirectHandle< Object >, N > &values)
Definition objects.cc:6250
static Handle< Derived > Put(Isolate *isolate, Handle< Derived > table, DirectHandle< Object > key, const std::array< DirectHandle< Object >, N > &values)
Definition objects.cc:6224
std::array< Tagged< Object >, N > Lookup(DirectHandle< Object > key)
Definition objects.cc:6188
static V8_EXPORT_PRIVATE DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< Object > input)
Definition objects.cc:687
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > ToLength(Isolate *isolate, DirectHandle< Object > input)
static V8_WARN_UNUSED_RESULT MaybeHandle< JSAny > GetPropertyWithAccessor(LookupIterator *it)
Definition objects.cc:1513
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Number > ConvertToLength(Isolate *isolate, DirectHandle< Object > input)
Definition objects.cc:732
static Tagged< Map > GetPrototypeChainRootMap(Tagged< Object > obj, Isolate *isolate)
Definition objects.cc:1683
static V8_WARN_UNUSED_RESULT Maybe< bool > RedefineIncompatibleProperty(Isolate *isolate, DirectHandle< Object > name, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
Definition objects.cc:2597
static bool ToArrayLength(Tagged< Object > obj, uint32_t *index)
static V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType ToString(Isolate *isolate, HandleType< T > input)
static V8_EXPORT_PRIVATE Handle< UnionOf< JSAny, Hole > > NewStorageFor(Isolate *isolate, Handle< UnionOf< JSAny, Hole > > object, Representation representation)
Definition objects.cc:240
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > AddDataProperty(LookupIterator *it, DirectHandle< Object > value, PropertyAttributes attributes, Maybe< ShouldThrow > should_throw, StoreOrigin store_origin, EnforceDefineSemantics semantics=EnforceDefineSemantics::kSet)
Definition objects.cc:2667
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) V8_WARN_UNUSED_RESULT static typename HandleType< Number > static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ConvertToInt32(Isolate *isolate, HandleType< Object > input)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > SetProperty(LookupIterator *it, DirectHandle< Object > value, StoreOrigin store_origin, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >())
Definition objects.cc:2439
static V8_WARN_UNUSED_RESULT HandleType< Name >::MaybeType ConvertToName(Isolate *isolate, HandleType< Object > input)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetPropertyWithDefinedSetter(DirectHandle< JSAny > receiver, DirectHandle< JSReceiver > setter, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
Definition objects.cc:1670
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToNumber(Isolate *isolate, HandleType< T > input)
static bool SameNumberValue(double number1, double number2)
static V8_WARN_UNUSED_RESULT MaybeHandle< JSAny > GetPropertyWithDefinedGetter(DirectHandle< JSAny > receiver, DirectHandle< JSReceiver > getter)
Definition objects.cc:1649
static bool SameValueZero(Tagged< Object > obj, Tagged< Object > other)
Definition objects.cc:1723
static DirectHandle< FieldType > OptimalType(Tagged< Object > obj, Isolate *isolate, Representation representation)
Definition objects.cc:224
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > OrdinaryHasInstance(Isolate *isolate, DirectHandle< JSAny > callable, DirectHandle< JSAny > object)
Definition objects.cc:1045
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ConvertToUint32(Isolate *isolate, HandleType< Object > input)
static Handle< String > TypeOf(Isolate *isolate, DirectHandle< Object > object)
Definition objects.cc:1001
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< FixedArray > CreateListFromArrayLike(Isolate *isolate, DirectHandle< Object > object, ElementTypes element_types)
Definition objects.cc:1176
static V8_EXPORT_PRIVATE bool BooleanValue(Tagged< Object > obj, IsolateT *isolate)
static V8_WARN_UNUSED_RESULT HandleType< JSReceiver >::MaybeType ToObject(Isolate *isolate, HandleType< T > object, const char *method_name=nullptr)
V8_INLINE static V8_WARN_UNUSED_RESULT Maybe< bool > IsArray(DirectHandle< Object > object)
static V8_EXPORT_PRIVATE Tagged< Smi > GetOrCreateHash(Tagged< Object > obj, Isolate *isolate)
Definition objects.cc:1696
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > Add(Isolate *isolate, Handle< Object > lhs, Handle< Object > rhs)
Definition objects.cc:1016
static bool FilterKey(Tagged< Object > obj, PropertyFilter filter)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > Equals(Isolate *isolate, DirectHandle< Object > x, DirectHandle< Object > y)
Definition objects.cc:886
static V8_WARN_UNUSED_RESULT Maybe< bool > SetSuperProperty(LookupIterator *it, DirectHandle< Object > value, StoreOrigin store_origin, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >())
Definition objects.cc:2455
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > InstanceOf(Isolate *isolate, DirectHandle< JSAny > object, DirectHandle< JSAny > callable)
Definition objects.cc:1085
static double NumberValue(Tagged< Number > obj)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetPropertyWithAccessor(LookupIterator *it, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
Definition objects.cc:1578
static V8_WARN_UNUSED_RESULT Maybe< bool > TransitionAndWriteDataProperty(LookupIterator *it, DirectHandle< Object > value, PropertyAttributes attributes, Maybe< ShouldThrow > should_throw, StoreOrigin store_origin)
Definition objects.cc:2737
static bool CheckContextualStoreToJSGlobalObject(LookupIterator *it, Maybe< ShouldThrow > should_throw)
Definition objects.cc:2419
static V8_EXPORT_PRIVATE MaybeDirectHandle< String > NoSideEffectsToMaybeString(Isolate *isolate, DirectHandle< Object > input)
Definition objects.cc:584
static Handle< JSAny > WrapForRead(IsolateT *isolate, Handle< JSAny > object, Representation representation)
Definition objects.cc:257
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetLengthFromArrayLike(Isolate *isolate, DirectHandle< JSReceiver > object)
Definition objects.cc:1238
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) V8_WARN_UNUSED_RESULT static typename HandleType< String > static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ConvertToNumber(Isolate *isolate, HandleType< Object > input)
static V8_EXPORT_PRIVATE bool SameValue(Tagged< Object > obj, Tagged< Object > other)
Definition objects.cc:1706
static V8_EXPORT_PRIVATE bool ToInt32(Tagged< Object > obj, int32_t *value)
Definition objects.cc:1438
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > ConvertReceiver(Isolate *isolate, DirectHandle< Object > object)
Definition objects.cc:305
static V8_WARN_UNUSED_RESULT HandleType< Object >::MaybeType ToPrimitive(Isolate *isolate, HandleType< T > input, ToPrimitiveHint hint=ToPrimitiveHint::kDefault)
static V8_WARN_UNUSED_RESULT Maybe< bool > CannotCreateProperty(Isolate *isolate, DirectHandle< JSAny > receiver, DirectHandle< Object > name, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
Definition objects.cc:2559
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > SpeciesConstructor(Isolate *isolate, DirectHandle< JSReceiver > recv, DirectHandle< JSFunction > default_ctor)
Definition objects.cc:1791
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetMethod(Isolate *isolate, DirectHandle< JSReceiver > receiver, DirectHandle< Name > name)
Definition objects.cc:1125
static V8_EXPORT_PRIVATE bool StrictEquals(Tagged< Object > obj, Tagged< Object > that)
Definition objects.cc:986
static Tagged< Object > ToBoolean(Tagged< Object > obj, Isolate *isolate)
Definition objects.cc:791
static V8_EXPORT_PRIVATE bool IterationHasObservableEffects(Tagged< Object > obj)
Definition objects.cc:1826
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
Definition objects.cc:1248
static bool ToUint32(Tagged< Object > obj, uint32_t *value)
static V8_WARN_UNUSED_RESULT Maybe< bool > WriteToReadOnlyProperty(LookupIterator *it, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
Definition objects.cc:2570
static HandleType< Object >::MaybeType ShareSlow(Isolate *isolate, HandleType< HeapObject > value, ShouldThrow throw_if_cannot_be_shared)
Definition objects.cc:2765
static V8_WARN_UNUSED_RESULT HandleType< Numeric >::MaybeType ConvertToNumeric(Isolate *isolate, HandleType< Object > input)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetDataProperty(LookupIterator *it, DirectHandle< Object > value)
Definition objects.cc:2604
static bool FitsRepresentation(Tagged< Object > obj, Representation representation, bool allow_coercion=true)
static V8_WARN_UNUSED_RESULT HandleType< Object >::MaybeType ConvertToPropertyKey(Isolate *isolate, HandleType< Object > value)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetPropertyInternal(LookupIterator *it, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw, StoreOrigin store_origin, bool *found)
Definition objects.cc:2267
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > ArraySpeciesConstructor(Isolate *isolate, DirectHandle< JSAny > original_array)
Definition objects.cc:1742
static Tagged< Object > GetSimpleHash(Tagged< Object > object)
static bool IsCodeLike(Tagged< Object > obj, Isolate *isolate)
Definition objects.cc:1860
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< ComparisonResult > Compare(Isolate *isolate, DirectHandle< Object > x, DirectHandle< Object > y)
Definition objects.cc:841
static HandleType< Object >::MaybeType Share(Isolate *isolate, HandleType< T > value, ShouldThrow throw_if_cannot_be_shared)
static V8_WARN_UNUSED_RESULT MaybeHandle< JSReceiver > ToObjectImpl(Isolate *isolate, DirectHandle< Object > object, const char *method_name=nullptr)
Definition objects.cc:273
static V8_WARN_UNUSED_RESULT HandleType< Object >::MaybeType ToNumeric(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT Handle< Number > ToNumber(Isolate *isolate, DirectHandle< Oddball > input)
Definition oddball-inl.h:54
Tagged< String > type_of() const
Definition oddball-inl.h:42
Tagged< String > to_string() const
Definition oddball-inl.h:32
uint8_t kind() const
Definition oddball-inl.h:47
Tagged< Number > to_number() const
Definition oddball-inl.h:37
static void Initialize(Isolate *isolate, DirectHandle< Oddball > oddball, const char *to_string, DirectHandle< Number > to_number, const char *type_of, uint8_t kind)
Definition objects.cc:4274
static HandleType< OrderedHashMap >::MaybeType Rehash(Isolate *isolate, HandleType< OrderedHashMap > table)
static HandleType< OrderedHashSet >::MaybeType Rehash(Isolate *isolate, HandleType< OrderedHashSet > table)
static Handle< OrderedHashSet > Clear(Isolate *isolate, Handle< OrderedHashSet > table)
static int SizeFor(int data_length, int children_length)
static const int kSizeOfAllPromiseReactionJobTasks
Definition promise.h:34
static constexpr int SizeFor(int length)
static const int kNoHashSentinel
static PropertyCellType InitialType(Isolate *isolate, Tagged< Object > value)
Definition objects.cc:6440
void ClearAndInvalidate(Isolate *isolate)
Definition objects.cc:6398
static Handle< PropertyCell > PrepareForAndSetValue(Isolate *isolate, DirectHandle< GlobalDictionary > dictionary, InternalIndex entry, DirectHandle< Object > value, PropertyDetails details)
Definition objects.cc:6473
static bool CheckDataIsCompatible(PropertyDetails details, Tagged< Object > value)
Definition objects.cc:6525
static Handle< PropertyCell > InvalidateAndReplaceEntry(Isolate *isolate, DirectHandle< GlobalDictionary > dictionary, InternalIndex entry, PropertyDetails new_details, DirectHandle< Object > new_value)
Definition objects.cc:6408
static PropertyCellType UpdatedType(Isolate *isolate, Tagged< PropertyCell > cell, Tagged< Object > value, PropertyDetails details)
Definition objects.cc:6447
void set_value(DirectHandle< JSAny > value)
static bool IsAccessorDescriptor(PropertyDescriptor *desc)
Handle< UnionOf< JSAny, FunctionTemplateInfo > > get() const
static void CompletePropertyDescriptor(Isolate *isolate, PropertyDescriptor *desc)
static bool ToPropertyDescriptor(Isolate *isolate, Handle< JSAny > obj, PropertyDescriptor *desc)
Handle< UnionOf< JSAny, FunctionTemplateInfo > > set() const
static bool IsDataDescriptor(PropertyDescriptor *desc)
PropertyAttributes attributes() const
PropertyDetails CopyWithConstness(PropertyConstness constness) const
PropertyLocation location() const
Representation representation() const
PropertyCellType cell_type() const
PropertyDetails set_index(int index) const
static bool IsValidIndex(int index)
static constexpr PropertyDetails Empty(PropertyCellType cell_type=PropertyCellType::kNoCell)
PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes) const
PropertyDetails set_cell_type(PropertyCellType type) const
Tagged< Smi > AsSmi() const
Definition objects-inl.h:79
PropertyDetails CopyWithRepresentation(Representation representation) const
static const int kProtectorValid
Definition protectors.h:15
static const int kProtectorInvalid
Definition protectors.h:16
static Handle< WeakArrayList > Add(Isolate *isolate, Handle< WeakArrayList > array, DirectHandle< Map > value, int *assigned_index)
Definition objects.cc:3775
static Tagged< WeakArrayList > Compact(DirectHandle< WeakArrayList > array, Heap *heap, CompactionCallback callback, AllocationType allocation=AllocationType::kYoung)
Definition objects.cc:3838
void(*)(Tagged< HeapObject > object, int from_index, int to_index) CompactionCallback
static void set_empty_slot_index(Tagged< WeakArrayList > array, int index)
static void ScanForEmptySlots(Tagged< WeakArrayList > array)
Definition objects.cc:3830
static const int kNoEmptySlotsMarker
static void MarkSlotEmpty(Tagged< WeakArrayList > array, int index)
static Tagged< Smi > empty_slot_index(Tagged< WeakArrayList > array)
static V8_EXPORT_PRIVATE bool Contains(Address address)
Tagged< Object > ValueAt(InternalIndex entry)
Definition objects.cc:6053
static Handle< RegisteredSymbolTable > Add(Isolate *isolate, Handle< RegisteredSymbolTable > table, DirectHandle< String > key, DirectHandle< Symbol >)
Definition objects.cc:5635
static char * RestoreState(Isolate *isolate, char *from)
Definition objects.cc:4097
static void Iterate(Isolate *isolate, RootVisitor *v)
Definition objects.cc:4108
static int ArchiveSpacePerThread()
Definition objects.cc:4087
static void PostGarbageCollectionProcessing(Isolate *isolate)
Definition objects.cc:4078
static char * ArchiveState(Isolate *isolate, char *to)
Definition objects.cc:4090
constexpr bool IsHeapObject() const
constexpr bool IsNone() const
bool Equals(const Representation &other) const
static constexpr Representation Tagged()
constexpr bool IsDouble() const
Iterator(Isolate *isolate)
Definition objects.cc:4792
Tagged< Script > Next()
Definition objects.cc:4795
V8_EXPORT_PRIVATE bool GetPositionInfoWithLineEnds(int position, PositionInfo *info, const String::LineEndsVector &line_ends, OffsetFlag offset_flag=OffsetFlag::kWithOffset) const
Definition objects.cc:4658
static void InitLineEnds(Isolate *isolate, DirectHandle< Script > script)
Definition script-inl.h:201
static V8_EXPORT_PRIVATE String::LineEndsVector GetLineEnds(Isolate *isolate, DirectHandle< Script > script)
Definition objects.cc:4316
static DirectHandle< String > GetScriptHash(Isolate *isolate, DirectHandle< Script > script, bool forceForInspector)
Definition objects.cc:4717
V8_EXPORT_PRIVATE void AddPositionInfoOffset(PositionInfo *info, OffsetFlag offset_flag=OffsetFlag::kWithOffset) const
Definition objects.cc:4581
bool IsSubjectToDebugging() const
Definition objects.cc:4383
bool GetPositionInfoInternal(const LineEndsContainer &ends, int position, Script::PositionInfo *info, const DisallowGarbageCollection &no_gc) const
Definition objects.cc:4595
static V8_EXPORT_PRIVATE int GetLineNumber(DirectHandle< Script > script, int code_offset)
Definition objects.cc:4698
void TraceScriptRundownSources()
Definition objects.cc:4443
bool has_line_ends() const
Definition script-inl.h:190
bool HasSourceURLComment() const
Definition script-inl.h:211
static MaybeHandle< SharedFunctionInfo > FindSharedFunctionInfo(DirectHandle< Script > script, IsolateT *isolate, FunctionLiteral *function_literal)
Definition objects.cc:4763
static void SetSource(Isolate *isolate, DirectHandle< Script > script, DirectHandle< String > source)
Definition objects.cc:4349
static void V8_PRESERVE_MOST InitLineEndsInternal(IsolateT *isolate, DirectHandle< Script > script)
Tagged< Object > GetNameOrSourceURL()
Definition objects.cc:4710
void set_flags(uint32_t new_flags)
Definition script-inl.h:131
v8::ScriptOriginOptions origin_options()
Definition script-inl.h:169
bool IsUserJavaScript() const
Definition objects.cc:4398
uint32_t flags() const
Definition script-inl.h:124
static bool GetPositionInfo(DirectHandle< Script > script, int position, PositionInfo *info, OffsetFlag offset_flag=OffsetFlag::kWithOffset)
Definition objects.cc:4367
bool HasSourceMappingURLComment() const
Definition script-inl.h:215
static int GetColumnNumber(DirectHandle< Script > script, int code_offset)
Definition objects.cc:4686
static int GetEvalPosition(Isolate *isolate, DirectHandle< Script > script)
Definition objects.cc:4294
static bool GetLineColumnWithLineEnds(int position, int &line, int &column, const String::LineEndsVector &line_ends)
Definition objects.cc:4669
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static void EnsureSourcePositionsAvailable(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared_info)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Handle< SimpleNumberDictionary > Set(Isolate *isolate, Handle< SimpleNumberDictionary > dictionary, uint32_t key, DirectHandle< Object > value)
Definition objects.cc:5852
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > ToUint32Smi(Tagged< Smi > smi)
Definition smi.h:27
static V8_EXPORT_PRIVATE Address LexicographicCompare(Isolate *isolate, Tagged< Smi > x, Tagged< Smi > y)
Definition objects.cc:6618
static constexpr Tagged< Smi > zero()
Definition smi.h:99
static V8_EXPORT_PRIVATE void SmiPrint(Tagged< Smi > smi, std::ostream &os)
Definition objects.cc:1913
static constexpr int kMaxValue
Definition smi.h:101
V8_EXPORT_PRIVATE bool Has(Isolate *isolate, DirectHandle< String > name)
Definition objects.cc:5631
static V8_EXPORT_PRIVATE Handle< StringSet > New(Isolate *isolate)
Definition objects.cc:5615
static V8_EXPORT_PRIVATE Handle< StringSet > Add(Isolate *isolate, Handle< StringSet > stringset, DirectHandle< String > name)
Definition objects.cc:5619
V8_INLINE bool IsSequentialOneByte() const
Definition string-inl.h:230
void Add(const char *format)
static void WriteToFlat(Tagged< String > source, SinkCharT *sink, uint32_t start, uint32_t length)
Definition string.cc:772
static const uint32_t kMaxLength
Definition string.h:511
static LineEndsVector CalculateLineEndsVector(IsolateT *isolate, DirectHandle< String > string, bool include_ending_line)
Definition string.cc:1164
static V8_WARN_UNUSED_RESULT ComparisonResult Compare(Isolate *isolate, DirectHandle< String > x, DirectHandle< String > y)
Definition string.cc:1353
static HandleType< String > Share(Isolate *isolate, HandleType< T > string)
Definition string-inl.h:946
base::SmallVector< int32_t, kInlineLineEndsSize > LineEndsVector
Definition string.h:642
static Handle< FixedArray > CalculateLineEnds(IsolateT *isolate, DirectHandle< String > string, bool include_ending_line)
Definition string.cc:1194
static HandleType< Number > ToNumber(Isolate *isolate, HandleType< String > subject)
Definition string.cc:661
bool Equals(Tagged< String > other) const
Definition string-inl.h:535
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1917
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1915
static constexpr int SizeFor(int capacity)
static HandleType< SwissNameDictionary > Add(IsolateT *isolate, HandleType< SwissNameDictionary > table, DirectHandle< Name > key, DirectHandle< Object > value, PropertyDetails details, InternalIndex *entry_out=nullptr)
const char * PrivateSymbolToName() const
Definition objects.cc:4984
void set(int index, Tagged< ElementT > value, WriteBarrierMode mode=kDefaultMode)
bool GetHeapObjectIfStrong(Tagged< HeapObject > *result) const
constexpr bool IsCleared() const
bool GetHeapObjectIfWeak(Tagged< HeapObject > *result) const
bool ToSmi(Tagged< Smi > *value) const
V8_INLINE constexpr bool is_null() const
Definition tagged.h:502
constexpr V8_INLINE bool IsSmi() const
Definition tagged.h:508
V8_INLINE constexpr int32_t value() const
Definition tagged.h:427
void BriefPrintDetails(std::ostream &os)
Definition objects.cc:1919
Tagged< Object > value1() const
Definition struct-inl.h:26
Tagged< Object > value2() const
Definition struct-inl.h:31
static int SizeFor(Tagged< Map > map, int length)
static constexpr int SizeFor(int length)
static constexpr int kSize
static int GcSafeSize(Tagged< Map > map)
static Handle< WeakArrayList > EnsureSpace(Isolate *isolate, Handle< WeakArrayList > array, int length, AllocationType allocation=AllocationType::kYoung)
static constexpr int SizeForCapacity(int capacity)
const WasmModule * module() const
static std::unique_ptr< TracedValue > Create()
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
Definition globals.h:242
#define V8_EXTERNAL_CODE_SPACE_BOOL
Definition globals.h:255
int start
uint32_t count
Handle< SharedFunctionInfo > info
int end
LineAndColumn current
#define RETURN_ON_EXCEPTION(isolate, call)
Definition isolate.h:395
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define RETURN_FAILURE(isolate, should_throw, call)
Definition isolate.h:398
#define THROW_NEW_ERROR(isolate, call)
Definition isolate.h:307
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
Definition isolate.h:276
#define RETURN_VALUE_IF_EXCEPTION(isolate, value)
Definition isolate.h:224
#define RETURN_EXCEPTION_IF_EXCEPTION(isolate)
Definition isolate.h:235
#define STACK_CHECK(isolate, result_value)
Definition isolate.h:3067
#define MAYBE_RETURN_NULL(call)
Definition isolate.h:413
#define MAYBE_RETURN(call, value)
Definition isolate.h:408
#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)
Definition isolate.h:340
MicrotaskQueue * microtask_queue
Definition execution.cc:77
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
#define V8_ALLOCATION_SITE_TRACKING_BOOL
#define PRIVATE_SYMBOL_LIST_GENERATOR(V, _)
TNode< Context > context
TNode< Object > target
TNode< Object > receiver
SharedFunctionInfoRef shared
TNode< Object > callback
std::map< const std::string, const std::string > map
#define WRITE_TYPE(TYPE)
ZoneVector< RpoNumber > & result
MovableLabel handler
ZoneVector< Entry > entries
std::optional< OolTrapLabel > trap
int x
Point to
int position
Definition liveedit.cc:290
uint32_t const mask
InstructionOperand source
int n
Definition mul-fft.cc:296
constexpr unsigned CountLeadingZeros(T value)
Definition bits.h:100
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
signed_type NegateWithWraparound(signed_type a)
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
Definition bounds.h:20
constexpr Vector< T > VectorOf(T *start, size_t size)
Definition vector.h:360
constexpr int kMinInt
Definition globals.h:375
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
bool TryCast(Tagged< From > value, Tagged< To > *out)
Definition casting.h:77
constexpr const char * ToString(DeoptimizeKind kind)
Definition globals.h:880
uint32_t DoubleToUint32(double x)
constexpr NullMaybeHandleType kNullMaybeHandle
constexpr double kMaxSafeInteger
Definition globals.h:1985
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
@ SKIP_WRITE_BARRIER
Definition objects.h:52
bool is_sloppy(LanguageMode language_mode)
Definition globals.h:773
constexpr bool IsHoleyElementsKind(ElementsKind kind)
bool ComparisonResultToBool(Operation op, ComparisonResult result)
Definition objects.cc:164
bool PropertyKeyToArrayIndex(DirectHandle< Object > index_obj, uint32_t *output)
Definition objects.cc:3114
bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, ElementsKind to_kind)
bool IsNumber(Tagged< Object > obj)
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
bool IsAnyHole(Tagged< Object > obj, PtrComprCageBase cage_base)
bool DoubleToBoolean(double d)
Definition utils.cc:208
@ USE_CUSTOM_MINIMUM_CAPACITY
Definition globals.h:1568
Tagged(T object) -> Tagged< T >
void FormatBytesToHex(char *formatted, size_t size_of_formatted, const uint8_t *val, size_t size_of_val)
Definition hex-format.cc:15
double DoubleToInteger(double x)
MaybeHandle< T > MaybeIndirectHandle
Definition globals.h:1109
UnionOf< Undefined, FunctionTemplateInfo > UnionOf< Undefined, InterceptorInfo > UnionOf< Undefined, ObjectTemplateInfo > AccessCheckInfo
V8_INLINE Isolate * GetIsolateFromWritableObject(Tagged< HeapObject > object)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
Definition handles.h:757
constexpr uint64_t kHoleNanInt64
Definition globals.h:1960
kInterpreterTrampolineOffset Tagged< HeapObject >
constexpr int N
int ToNumber(Register reg)
kStaticElementsTemplateOffset kInstancePropertiesTemplateOffset Tagged< FixedArray >
void MemsetTagged(Tagged_t *start, Tagged< MaybeObject > value, size_t counter)
Definition slots-inl.h:486
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
double FastI2D(int x)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
return Cast< NumberDictionary >(elements(cage_base))
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
const int kVariableSizeSentinel
Definition objects.h:84
constexpr int kInvalidInfoId
Definition globals.h:2766
bool IsNullOrUndefined(Tagged< Object > obj, Isolate *isolate)
Handle< To > UncheckedCast(Handle< From > value)
Definition handles-inl.h:55
bool IsFastPackedElementsKind(ElementsKind kind)
static void MoveMessageToPromise(Isolate *isolate, DirectHandle< JSPromise > promise)
Definition objects.cc:5049
V8_INLINE PtrComprCageBase GetPtrComprCageBase()
const uint8_t * SHA256_hash(const void *data, size_t len, uint8_t *digest)
Definition sha-256.cc:167
Handle< T > IndirectHandle
Definition globals.h:1086
bool IsModule(FunctionKind kind)
ShouldThrow GetShouldThrow(Isolate *isolate, Maybe< ShouldThrow > should_throw)
Definition objects.cc:140
bool IsShared(Tagged< Object > obj)
void ShortPrint(Tagged< Object > obj, FILE *out)
Definition objects.cc:1865
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
bool IsBigIntTypedArrayElementsKind(ElementsKind kind)
static bool RemainsConstantType(Tagged< PropertyCell > cell, Tagged< Object > value)
Definition objects.cc:6426
@ SHARED_SEQ_ONE_BYTE_STRING_TYPE
@ SHARED_SEQ_TWO_BYTE_STRING_TYPE
@ INTERNALIZED_ONE_BYTE_STRING_TYPE
@ INTERNALIZED_TWO_BYTE_STRING_TYPE
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
Definition tagged.h:893
static const int kMaxNumberOfDescriptors
int32_t DoubleToInt32(double x)
const int kHeapObjectTag
Definition v8-internal.h:72
int FastD2I(double x)
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:669
V8_EXPORT_PRIVATE FlagValues v8_flags
bool IsUniqueName(Tagged< Name > obj)
V8_INLINE bool IsWasmObject(T obj, Isolate *=nullptr)
Definition objects.h:725
bool PropertyKeyToArrayLength(DirectHandle< Object > value, uint32_t *length)
Definition objects.cc:3107
@ kExternalBigInt64Array
Definition globals.h:2463
@ kExternalBigUint64Array
Definition globals.h:2464
static bool ShouldConvertToSlowElements(uint32_t used_elements, uint32_t new_capacity)
return value
Definition map-inl.h:893
constexpr int kMaxInt
Definition globals.h:374
EnforceDefineSemantics
Definition objects.h:116
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit Map::Bits1::IsUndetectableBit Map::Bits1::IsConstructorBit Map::Bits2::IsImmutablePrototypeBit Map::Bits3::IsDeprecatedBit Map::Bits3::IsPrototypeMapBit is_extensible
Definition map-inl.h:137
constexpr uint32_t kMaxUInt32
Definition globals.h:387
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
Definition map-inl.h:70
uint32_t GetLength(Tagged< JSArray > array)
Definition api.cc:8179
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset prototype
Definition map-inl.h:69
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr ReleaseStoreTag kReleaseStore
Definition globals.h:2910
Local< T > Handle
@ kPromiseRejectWithNoHandler
Definition v8-promise.h:148
Maybe< T > Nothing()
Definition v8-maybe.h:112
static constexpr RelaxedLoadTag kRelaxedLoad
Definition globals.h:2909
static constexpr RelaxedStoreTag kRelaxedStore
Definition globals.h:2911
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
Maybe< T > Just(const T &t)
Definition v8-maybe.h:117
#define SIMPLE_HEAP_OBJECT_LIST2(V)
#define INSTANCE_TYPE_LIST(V)
#define EXTERN_DEFINE_DICTIONARY(DERIVED, SHAPE)
Definition objects.cc:6755
#define EXTERN_DEFINE_MULTI_OBJECT_BASE_HASH_TABLE(DERIVED, N)
Definition objects.cc:6750
#define MAKE_TORQUE_SIZE_FOR(TYPE, TypeName)
#define EXTERN_DEFINE_HASH_TABLE(DERIVED, SHAPE)
Definition objects.cc:6716
#define EXTERN_DEFINE_BASE_NAME_DICTIONARY(DERIVED, SHAPE)
Definition objects.cc:6788
#define SYMBOL_CHECK_AND_PRINT(_, name)
#define EXTERN_DEFINE_OBJECT_BASE_HASH_TABLE(DERIVED, SHAPE)
Definition objects.cc:6745
const size_t kSizeOfFormattedSha256Digest
Definition sha-256.h:44
const size_t kSizeOfSha256Digest
Definition sha-256.h:43
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK(condition)
Definition logging.h:124
#define CHECK_GT(lhs, rhs)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define CHECK_NE(lhs, rhs)
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
#define USE(...)
Definition macros.h:293
#define V8_EXPORT_PRIVATE
Definition macros.h:460
const Address value
Definition objects.h:646
std::vector< WasmFunction > functions
#define TRACE_DISABLED_BY_DEFAULT(name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define V8_LIKELY(condition)
Definition v8config.h:661
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
#define V8_UNLIKELY(condition)
Definition v8config.h:660
wasm::ValueType type