/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/builtins/builtins-struct.cc
214 строк
7 KB
Michaël Zasso
deps: update V8 to 14.1.146.11
04 окт 2025, 19:47
Не верифицирован
04 окт 2025, 19:47
7772a2d
Код
Авторство
О чём код?
// Copyright 2022 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <unordered_set> #include "src/builtins/builtins-utils-inl.h" #include "src/objects/js-struct-inl.h" #include "src/objects/property-details.h" namespace v8 { namespace internal { constexpr int kMaxJSStructFields = 999; // Note: For Wasm structs, we currently allow 2000 fields, because there was // specific demand for that. Ideally we'd have the same limit, but JS structs // rely on DescriptorArrays and are hence limited to 1020 fields at most. static_assert(kMaxJSStructFields <= kMaxNumberOfDescriptors); namespace { struct NameHandleHasher { size_t operator()(IndirectHandle<Name> name) const { return name->hash(); } }; struct UniqueNameHandleEqual { bool operator()(IndirectHandle<Name> x, IndirectHandle<Name> y) const { DCHECK(IsUniqueName(*x)); DCHECK(IsUniqueName(*y)); return *x == *y; } }; using UniqueNameHandleSet = std::unordered_set<IndirectHandle<Name>, NameHandleHasher, UniqueNameHandleEqual>; } // namespace BUILTIN(SharedSpaceJSObjectHasInstance) { HandleScope scope(isolate); DirectHandle<Object> constructor = args.receiver(); if (!IsJSFunction(*constructor)) { return *isolate->factory()->false_value(); } bool result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, AlwaysSharedSpaceJSObject::HasInstance( isolate, Cast<JSFunction>(constructor), args.atOrUndefined(isolate, 1))); return *isolate->factory()->ToBoolean(result); } namespace { Maybe<bool> CollectFieldsAndElements(Isolate* isolate, DirectHandle<JSReceiver> property_names, int num_properties, DirectHandleVector<Name>& field_names, std::set<uint32_t>& element_names) { Handle<Object> raw_property_name; Handle<Name> property_name; UniqueNameHandleSet field_names_set; for (int i = 0; i < num_properties; i++) { ASSIGN_RETURN_ON_EXCEPTION( isolate, raw_property_name, JSReceiver::GetElement(isolate, property_names, i)); ASSIGN_RETURN_ON_EXCEPTION(isolate, property_name, Object::ToName(isolate, raw_property_name)); bool is_duplicate; size_t index; if (!property_name->AsIntegerIndex(&index) || index > JSObject::kMaxElementIndex) { property_name = isolate->factory()->InternalizeName(property_name); // TODO(v8:12547): Support Symbols? if (IsSymbol(*property_name)) { THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString)); } is_duplicate = !field_names_set.insert(property_name).second; // Keep the field names in the original order. if (!is_duplicate) field_names.push_back(property_name); } else { is_duplicate = !element_names.insert(static_cast<uint32_t>(index)).second; } if (is_duplicate) { THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kDuplicateTemplateProperty, property_name)); } } return Just(true); } } // namespace BUILTIN(SharedStructTypeConstructor) { DCHECK(v8_flags.shared_string_table); HandleScope scope(isolate); auto* factory = isolate->factory(); DirectHandle<Map> instance_map; { // Step 1: Collect the struct's property names and create the instance map. DirectHandle<JSReceiver> property_names_arg; if (!IsJSReceiver(*args.atOrUndefined(isolate, 1))) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kArgumentIsNonObject, factory->NewStringFromAsciiChecked("property names"))); } property_names_arg = args.at<JSReceiver>(1); // Treat property_names_arg as arraylike. DirectHandle<Object> raw_length_number; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, raw_length_number, Object::GetLengthFromArrayLike(isolate, property_names_arg)); double num_properties_double = Object::NumberValue(*raw_length_number); if (num_properties_double < 0 || num_properties_double > kMaxJSStructFields) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewRangeError(MessageTemplate::kStructFieldCountOutOfRange)); } int num_properties = static_cast<int>(num_properties_double); DirectHandleVector<Name> field_names(isolate); std::set<uint32_t> element_names; if (num_properties != 0) { MAYBE_RETURN( CollectFieldsAndElements(isolate, property_names_arg, num_properties, field_names, element_names), ReadOnlyRoots(isolate).exception()); } if (IsUndefined(*args.atOrUndefined(isolate, 2), isolate)) { // Create a new instance map if this type isn't registered. instance_map = JSSharedStruct::CreateInstanceMap( isolate, base::VectorOf(field_names), element_names, {}); } else { // Otherwise, get the canonical map. if (!IsString(*args.atOrUndefined(isolate, 2))) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kArgumentIsNonString, factory->NewStringFromAsciiChecked( "type registry key"))); } ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, instance_map, isolate->shared_struct_type_registry()->Register( isolate, args.at<String>(2), base::VectorOf(field_names), element_names)); } } // Step 2: Creat the JSFunction constructor. This is always created anew, // regardless of whether the type is registered. DirectHandle<SharedFunctionInfo> info = isolate->factory()->NewSharedFunctionInfoForBuiltin( isolate->factory()->empty_string(), Builtin::kSharedStructConstructor, 0, kAdapt); DirectHandle<JSFunction> constructor = Factory::JSFunctionBuilder{isolate, info, isolate->native_context()} .set_map(isolate->strict_function_with_readonly_prototype_map()) .Build(); constructor->set_prototype_or_initial_map(*instance_map, kReleaseStore); JSObject::AddProperty( isolate, constructor, factory->has_instance_symbol(), direct_handle( isolate->native_context()->shared_space_js_object_has_instance(), isolate), ALL_ATTRIBUTES_MASK); return *constructor; } BUILTIN(SharedStructConstructor) { HandleScope scope(isolate); DirectHandle<JSFunction> constructor(args.target()); DirectHandle<Map> instance_map(constructor->initial_map(), isolate); return *isolate->factory()->NewJSSharedStruct( args.target(), JSSharedStruct::GetElementsTemplate(isolate, *instance_map)); } BUILTIN(SharedStructTypeIsSharedStruct) { HandleScope scope(isolate); return isolate->heap()->ToBoolean( IsJSSharedStruct(*args.atOrUndefined(isolate, 1))); } BUILTIN(AtomicsMutexIsMutex) { HandleScope scope(isolate); return isolate->heap()->ToBoolean( IsJSAtomicsMutex(*args.atOrUndefined(isolate, 1))); } BUILTIN(AtomicsConditionIsCondition) { HandleScope scope(isolate); return isolate->heap()->ToBoolean( IsJSAtomicsCondition(*args.atOrUndefined(isolate, 1))); } } // namespace internal } // namespace v8