Commit 3834c637 authored by Seth Brenith's avatar Seth Brenith Committed by Commit Bot

[torque] Stricter object field verification, part 1

This change adjusts object initialization order for a few classes so
that the GC can never see those objects in an invalid, partially-
initialized state.

AccessorInfo: Just zeros out a few fields upon construction. This is the
simplest case.

FunctionTemplateInfo: Slightly changes the order in which fields are
set, so that the Smi field is set ahead of the call to SetCallHandler,
which can GC. Also a pretty simple case.

JSListFormat, JSPluralRules, JSRelativeTimeFormat, JSSegmenter: The spec
requires that we start with OrdinaryCreateFromConstructor, which has
observable side effects (it fetches the prototype from the new.target).
So we split JSObject::New in half: the first half does all of the user-
visible things and returns a Map, which we can pass to the second half
when we're ready to actually allocate the object.

JSTypedArray: Extends the pattern from JSListFormat into Torque code:
start with a Map and don't allocate the object until we're ready to set
all of its properties.

Bug: v8:9311
Change-Id: Id7703e8a0727ec756c774cfbb56af787658a111a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1646844
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62123}
parent 2f2657a6
...@@ -1434,17 +1434,21 @@ static Local<FunctionTemplate> FunctionTemplateNew( ...@@ -1434,17 +1434,21 @@ static Local<FunctionTemplate> FunctionTemplateNew(
i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld); i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
i::Handle<i::FunctionTemplateInfo> obj = i::Handle<i::FunctionTemplateInfo> obj =
i::Handle<i::FunctionTemplateInfo>::cast(struct_obj); i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
InitializeFunctionTemplate(obj); {
obj->set_do_not_cache(do_not_cache); // Disallow GC until all fields of obj have acceptable types.
int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber; i::DisallowHeapAllocation no_gc;
if (!do_not_cache) { InitializeFunctionTemplate(obj);
next_serial_number = isolate->heap()->GetNextTemplateSerialNumber(); obj->set_length(length);
obj->set_do_not_cache(do_not_cache);
int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber;
if (!do_not_cache) {
next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
}
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
} }
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
if (callback != nullptr) { if (callback != nullptr) {
Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type); Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type);
} }
obj->set_length(length);
obj->set_undetectable(false); obj->set_undetectable(false);
obj->set_needs_access_check(false); obj->set_needs_access_check(false);
obj->set_accept_any_receiver(true); obj->set_accept_any_receiver(true);
......
...@@ -317,6 +317,16 @@ macro GetDerivedMap(implicit context: Context)( ...@@ -317,6 +317,16 @@ macro GetDerivedMap(implicit context: Context)(
} }
} }
macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map):
JSObject {
let properties = kEmptyFixedArray;
if (IsDictionaryMap(map)) {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
return AllocateJSObjectFromMap(
map, properties, kEmptyFixedArray, kNone, kWithSlackTracking);
}
extern class JSFunction extends JSObject { extern class JSFunction extends JSObject {
shared_function_info: SharedFunctionInfo; shared_function_info: SharedFunctionInfo;
context: Context; context: Context;
...@@ -633,30 +643,6 @@ extern class JSArrayBufferView extends JSObject { ...@@ -633,30 +643,6 @@ extern class JSArrayBufferView extends JSObject {
} }
extern class JSTypedArray extends JSArrayBufferView { extern class JSTypedArray extends JSArrayBufferView {
AttachOffHeapBuffer(buffer: JSArrayBuffer, byteOffset: uintptr): void {
const basePointer: Smi = 0;
// The max byteOffset is 8 * MaxSmi on the particular platform. 32 bit
// platforms are self-limiting, because we can't allocate an array bigger
// than our 32-bit arithmetic range anyway. 64 bit platforms could
// theoretically have an offset up to 2^35 - 1.
const backingStore = buffer.backing_store;
const externalPointer = backingStore + Convert<intptr>(byteOffset);
// Assert no overflow has occurred. Only assert if the mock array buffer
// allocator is NOT used. When the mock array buffer is used, impossibly
// large allocations are allowed that would erroneously cause an overflow
// and this assertion to fail.
assert(
IsMockArrayBufferAllocatorFlag() ||
Convert<uintptr>(externalPointer) >= Convert<uintptr>(backingStore));
this.elements = kEmptyByteArray;
this.buffer = buffer;
this.external_pointer = externalPointer;
this.base_pointer = basePointer;
}
length: uintptr; length: uintptr;
external_pointer: RawPtr; external_pointer: RawPtr;
base_pointer: ByteArray | Smi; base_pointer: ByteArray | Smi;
...@@ -729,7 +715,7 @@ extern class FunctionTemplateInfo extends TemplateInfo { ...@@ -729,7 +715,7 @@ extern class FunctionTemplateInfo extends TemplateInfo {
function_template_rare_data: Object; function_template_rare_data: Object;
shared_function_info: Object; shared_function_info: Object;
flag: Smi; flag: Smi;
@noVerifier length: Smi; length: Smi;
cached_property_name: Object; cached_property_name: Object;
} }
...@@ -964,9 +950,9 @@ const kAllowLargeObjectAllocation: constexpr AllocationFlags ...@@ -964,9 +950,9 @@ const kAllowLargeObjectAllocation: constexpr AllocationFlags
generates 'CodeStubAssembler::kAllowLargeObjectAllocation'; generates 'CodeStubAssembler::kAllowLargeObjectAllocation';
const kWithSlackTracking: constexpr SlackTrackingMode const kWithSlackTracking: constexpr SlackTrackingMode
generates 'SlackTrackingMode::kWithSlackTracking'; generates 'CodeStubAssembler::SlackTrackingMode::kWithSlackTracking';
const kNoSlackTracking: constexpr SlackTrackingMode const kNoSlackTracking: constexpr SlackTrackingMode
generates 'SlackTrackingMode::kNoSlackTracking'; generates 'CodeStubAssembler::SlackTrackingMode::kNoSlackTracking';
const kFixedDoubleArrays: constexpr ExtractFixedArrayFlags const kFixedDoubleArrays: constexpr ExtractFixedArrayFlags
generates 'CodeStubAssembler::ExtractFixedArrayFlag::kFixedDoubleArrays'; generates 'CodeStubAssembler::ExtractFixedArrayFlag::kFixedDoubleArrays';
...@@ -1075,6 +1061,12 @@ const kStrictReadOnlyProperty: constexpr MessageTemplate ...@@ -1075,6 +1061,12 @@ const kStrictReadOnlyProperty: constexpr MessageTemplate
const kString: constexpr PrimitiveType const kString: constexpr PrimitiveType
generates 'PrimitiveType::kString'; generates 'PrimitiveType::kString';
const kExternalPointerForOnHeapArray: constexpr RawPtr
generates 'JSTypedArray::ExternalPointerForOnHeapArray()';
const kNameDictionaryInitialCapacity:
constexpr int32 generates 'NameDictionary::kInitialCapacity';
type Hole extends Oddball; type Hole extends Oddball;
type Null extends Oddball; type Null extends Oddball;
type Undefined extends Oddball; type Undefined extends Oddball;
...@@ -1237,9 +1229,9 @@ extern class AccessorInfo extends Struct { ...@@ -1237,9 +1229,9 @@ extern class AccessorInfo extends Struct {
name: Object; name: Object;
flags: Smi; flags: Smi;
expected_receiver_type: Object; expected_receiver_type: Object;
@noVerifier setter: Foreign | Zero; setter: Foreign | Zero;
@noVerifier getter: Foreign | Zero; getter: Foreign | Zero;
@noVerifier js_getter: Foreign | Zero; js_getter: Foreign | Zero;
data: Object; data: Object;
} }
...@@ -1446,6 +1438,10 @@ extern macro ConstructWithTarget(implicit context: Context)( ...@@ -1446,6 +1438,10 @@ extern macro ConstructWithTarget(implicit context: Context)(
extern macro SpeciesConstructor(implicit context: Context)( extern macro SpeciesConstructor(implicit context: Context)(
Object, JSReceiver): JSReceiver; Object, JSReceiver): JSReceiver;
extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool;
extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32):
NameDictionary;
extern builtin ToObject(Context, Object): JSReceiver; extern builtin ToObject(Context, Object): JSReceiver;
extern macro ToObject_Inline(Context, Object): JSReceiver; extern macro ToObject_Inline(Context, Object): JSReceiver;
extern macro IsNullOrUndefined(Object): bool; extern macro IsNullOrUndefined(Object): bool;
...@@ -2062,6 +2058,7 @@ extern macro Int32Constant(constexpr ElementsKind): ElementsKind; ...@@ -2062,6 +2058,7 @@ extern macro Int32Constant(constexpr ElementsKind): ElementsKind;
extern macro IntPtrConstant(constexpr NativeContextSlot): NativeContextSlot; extern macro IntPtrConstant(constexpr NativeContextSlot): NativeContextSlot;
extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot;
extern macro IntPtrConstant(constexpr intptr): intptr; extern macro IntPtrConstant(constexpr intptr): intptr;
extern macro PointerConstant(constexpr RawPtr): RawPtr;
extern macro SingleCharacterStringConstant(constexpr string): String; extern macro SingleCharacterStringConstant(constexpr string): String;
extern macro BitcastWordToTaggedSigned(intptr): Smi; extern macro BitcastWordToTaggedSigned(intptr): Smi;
......
...@@ -3,13 +3,6 @@ ...@@ -3,13 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
namespace boolean { namespace boolean {
const kNameDictionaryInitialCapacity:
constexpr int32 generates 'NameDictionary::kInitialCapacity';
extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool;
extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32):
NameDictionary;
// TODO(v8:9120): This is a workaround to get access to target and new.target // TODO(v8:9120): This is a workaround to get access to target and new.target
// in javascript builtins. Requires cleanup once this is fully supported by // in javascript builtins. Requires cleanup once this is fully supported by
// torque. // torque.
...@@ -29,13 +22,8 @@ namespace boolean { ...@@ -29,13 +22,8 @@ namespace boolean {
const target = UnsafeCast<JSFunction>(Parameter(TARGET_INDEX)); const target = UnsafeCast<JSFunction>(Parameter(TARGET_INDEX));
const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget)); const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget));
let properties = kEmptyFixedArray;
if (IsDictionaryMap(map)) {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
const obj = UnsafeCast<JSValue>(AllocateJSObjectFromMap( const obj = UnsafeCast<JSValue>(AllocateFastOrSlowJSObjectFromMap(map));
map, properties, kEmptyFixedArray, kNone, kWithSlackTracking));
obj.value = value; obj.value = value;
return obj; return obj;
} }
......
...@@ -351,21 +351,17 @@ Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate, ...@@ -351,21 +351,17 @@ Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
Handle<JSFunction> target = args.target(); Handle<JSFunction> target = args.target();
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
Handle<JSObject> obj; Handle<Map> map;
// 2. Let result be OrdinaryCreateFromConstructor(NewTarget, // 2. Let result be OrdinaryCreateFromConstructor(NewTarget,
// "%<T>Prototype%"). // "%<T>Prototype%").
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, obj, isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
JSObject::New(target, new_target, Handle<AllocationSite>::null()));
Handle<T> result = Handle<T>::cast(obj);
result->set_flags(0);
Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> locales = args.atOrUndefined(isolate, 1);
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
// 3. Return Initialize<T>(t, locales, options). // 3. Return New<T>(t, locales, options).
RETURN_RESULT_OR_FAILURE(isolate, RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options));
T::Initialize(isolate, result, locales, options));
} }
/** /**
......
...@@ -27,23 +27,9 @@ using TNode = compiler::TNode<T>; ...@@ -27,23 +27,9 @@ using TNode = compiler::TNode<T>;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects // ES6 section 22.2 TypedArray Objects
// Setup the TypedArray which is under construction. // Sets the embedder fields to 0 for a TypedArray which is under construction.
// - Set the length. void TypedArrayBuiltinsAssembler::SetupTypedArrayEmbedderFields(
// - Set the byte_offset. TNode<JSTypedArray> holder) {
// - Set the byte_length.
// - Set EmbedderFields to 0.
void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
TNode<UintPtrT> length,
TNode<UintPtrT> byte_offset,
TNode<UintPtrT> byte_length) {
StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kLengthOffset, length,
MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
byte_offset,
MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteLengthOffset,
byte_length,
MachineType::PointerRepresentation());
for (int offset = JSTypedArray::kHeaderSize; for (int offset = JSTypedArray::kHeaderSize;
offset < JSTypedArray::kSizeWithEmbedderFields; offset += kTaggedSize) { offset < JSTypedArray::kSizeWithEmbedderFields; offset += kTaggedSize) {
StoreObjectField(holder, offset, SmiConstant(0)); StoreObjectField(holder, offset, SmiConstant(0));
...@@ -54,8 +40,7 @@ void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder, ...@@ -54,8 +40,7 @@ void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
// elements. // elements.
// TODO(bmeurer,v8:4153): Rename this and maybe fix up the implementation a bit. // TODO(bmeurer,v8:4153): Rename this and maybe fix up the implementation a bit.
TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
TNode<Context> context, TNode<JSTypedArray> holder, TNode<Context> context, TNode<UintPtrT> byte_length) {
TNode<UintPtrT> byte_length) {
TNode<Context> native_context = LoadNativeContext(context); TNode<Context> native_context = LoadNativeContext(context);
TNode<Map> map = TNode<Map> map =
CAST(LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX)); CAST(LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX));
...@@ -97,16 +82,6 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( ...@@ -97,16 +82,6 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
offset < JSArrayBuffer::kSizeWithEmbedderFields; offset += kTaggedSize) { offset < JSArrayBuffer::kSizeWithEmbedderFields; offset += kTaggedSize) {
StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(0)); StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(0));
} }
StoreObjectField(holder, JSTypedArray::kBufferOffset, buffer);
TNode<ByteArray> elements = AllocateByteArray(byte_length);
StoreObjectField(holder, JSTypedArray::kElementsOffset, elements);
StoreObjectField(holder, JSTypedArray::kBasePointerOffset, elements);
StoreObjectFieldNoWriteBarrier(
holder, JSTypedArray::kExternalPointerOffset,
PointerConstant(JSTypedArray::ExternalPointerForOnHeapArray()),
MachineType::PointerRepresentation());
return buffer; return buffer;
} }
...@@ -228,7 +203,12 @@ TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize( ...@@ -228,7 +203,12 @@ TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize(
TorqueStructTypedArrayElementsInfo TorqueStructTypedArrayElementsInfo
TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo( TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(
TNode<JSTypedArray> typed_array) { TNode<JSTypedArray> typed_array) {
TNode<Int32T> elements_kind = LoadElementsKind(typed_array); return GetTypedArrayElementsInfo(LoadMap(typed_array));
}
TorqueStructTypedArrayElementsInfo
TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(TNode<Map> map) {
TNode<Int32T> elements_kind = LoadMapElementsKind(map);
TVARIABLE(UintPtrT, var_size_log2); TVARIABLE(UintPtrT, var_size_log2);
TVARIABLE(Map, var_map); TVARIABLE(Map, var_map);
ReadOnlyRoots roots(isolate()); ReadOnlyRoots roots(isolate());
......
...@@ -27,15 +27,12 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { ...@@ -27,15 +27,12 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
const char* method_name, const char* method_name,
IterationKind iteration_kind); IterationKind iteration_kind);
void SetupTypedArray(TNode<JSTypedArray> holder, TNode<UintPtrT> length, void SetupTypedArrayEmbedderFields(TNode<JSTypedArray> holder);
TNode<UintPtrT> byte_offset,
TNode<UintPtrT> byte_length);
void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer, void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer,
TNode<Map> map, TNode<Smi> length, TNode<Map> map, TNode<Smi> length,
TNode<UintPtrT> byte_offset); TNode<UintPtrT> byte_offset);
TNode<JSArrayBuffer> AllocateEmptyOnHeapBuffer(TNode<Context> context, TNode<JSArrayBuffer> AllocateEmptyOnHeapBuffer(TNode<Context> context,
TNode<JSTypedArray> holder,
TNode<UintPtrT> byte_length); TNode<UintPtrT> byte_length);
TNode<Map> LoadMapForType(TNode<JSTypedArray> array); TNode<Map> LoadMapForType(TNode<JSTypedArray> array);
...@@ -54,6 +51,7 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { ...@@ -54,6 +51,7 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
// Returns information (byte size and map) about a TypedArray's elements. // Returns information (byte size and map) about a TypedArray's elements.
ElementsInfo GetTypedArrayElementsInfo(TNode<JSTypedArray> typed_array); ElementsInfo GetTypedArrayElementsInfo(TNode<JSTypedArray> typed_array);
ElementsInfo GetTypedArrayElementsInfo(TNode<Map> map);
TNode<JSFunction> GetDefaultConstructor(TNode<Context> context, TNode<JSFunction> GetDefaultConstructor(TNode<Context> context,
TNode<JSTypedArray> exemplar); TNode<JSTypedArray> exemplar);
......
...@@ -65,6 +65,8 @@ namespace typed_array { ...@@ -65,6 +65,8 @@ namespace typed_array {
implicit context: Context)(JSTypedArray): JSArrayBuffer; implicit context: Context)(JSTypedArray): JSArrayBuffer;
extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo( extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(
JSTypedArray): TypedArrayElementsInfo; JSTypedArray): TypedArrayElementsInfo;
extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(Map):
TypedArrayElementsInfo;
extern macro TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind( extern macro TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
ElementsKind): bool; ElementsKind): bool;
extern macro LoadFixedTypedArrayElementAsTagged( extern macro LoadFixedTypedArrayElementAsTagged(
......
...@@ -1536,6 +1536,7 @@ void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) { ...@@ -1536,6 +1536,7 @@ void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) {
void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) { void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSArrayBufferViewVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSArrayBufferViewVerify(*this, isolate);
CHECK(buffer().IsJSArrayBuffer());
CHECK_LE(byte_length(), JSArrayBuffer::kMaxByteLength); CHECK_LE(byte_length(), JSArrayBuffer::kMaxByteLength);
CHECK_LE(byte_offset(), JSArrayBuffer::kMaxByteLength); CHECK_LE(byte_offset(), JSArrayBuffer::kMaxByteLength);
} }
...@@ -1873,6 +1874,8 @@ void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) { ...@@ -1873,6 +1874,8 @@ void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
void JSListFormat::JSListFormatVerify(Isolate* isolate) { void JSListFormat::JSListFormatVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSListFormatVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSListFormatVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_formatter().IsForeign());
VerifySmiField(kFlagsOffset); VerifySmiField(kFlagsOffset);
} }
...@@ -1885,11 +1888,16 @@ void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) { ...@@ -1885,11 +1888,16 @@ void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) { void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSPluralRulesVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSPluralRulesVerify(*this, isolate);
CHECK(locale().IsString());
VerifySmiField(kFlagsOffset); VerifySmiField(kFlagsOffset);
CHECK(icu_plural_rules().IsForeign());
CHECK(icu_number_formatter().IsForeign());
} }
void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) { void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSRelativeTimeFormatVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSRelativeTimeFormatVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_formatter().IsForeign());
VerifySmiField(kFlagsOffset); VerifySmiField(kFlagsOffset);
} }
...@@ -1900,6 +1908,8 @@ void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) { ...@@ -1900,6 +1908,8 @@ void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) { void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSSegmenterVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSSegmenterVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_break_iterator().IsForeign());
VerifySmiField(kFlagsOffset); VerifySmiField(kFlagsOffset);
} }
......
...@@ -104,6 +104,15 @@ Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, ...@@ -104,6 +104,15 @@ Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
allocation); allocation);
} }
Handle<JSObject> Factory::NewFastOrSlowJSObjectFromMap(
Handle<Map> map, int number_of_slow_properties, AllocationType allocation,
Handle<AllocationSite> allocation_site) {
return map->is_dictionary_map()
? NewSlowJSObjectFromMap(map, number_of_slow_properties,
allocation, allocation_site)
: NewJSObjectFromMap(map, allocation, allocation_site);
}
Handle<Object> Factory::NewURIError() { Handle<Object> Factory::NewURIError() {
return NewError(isolate()->uri_error_function(), return NewError(isolate()->uri_error_function(),
MessageTemplate::kURIMalformed); MessageTemplate::kURIMalformed);
......
...@@ -1640,10 +1640,17 @@ Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry( ...@@ -1640,10 +1640,17 @@ Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
Handle<AccessorInfo> Factory::NewAccessorInfo() { Handle<AccessorInfo> Factory::NewAccessorInfo() {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast( Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(
NewStruct(ACCESSOR_INFO_TYPE, AllocationType::kOld)); NewStruct(ACCESSOR_INFO_TYPE, AllocationType::kOld));
DisallowHeapAllocation no_gc;
info->set_name(*empty_string()); info->set_name(*empty_string());
info->set_flags(0); // Must clear the flags, it was initialized as undefined. info->set_flags(0); // Must clear the flags, it was initialized as undefined.
info->set_is_sloppy(true); info->set_is_sloppy(true);
info->set_initial_property_attributes(NONE); info->set_initial_property_attributes(NONE);
// Clear some other fields that should not be undefined.
info->set_getter(Smi::kZero);
info->set_setter(Smi::kZero);
info->set_js_getter(Smi::kZero);
return info; return info;
} }
...@@ -2886,12 +2893,14 @@ Handle<JSObject> Factory::NewJSObjectFromMap( ...@@ -2886,12 +2893,14 @@ Handle<JSObject> Factory::NewJSObjectFromMap(
return js_obj; return js_obj;
} }
Handle<JSObject> Factory::NewSlowJSObjectFromMap(Handle<Map> map, int capacity, Handle<JSObject> Factory::NewSlowJSObjectFromMap(
AllocationType allocation) { Handle<Map> map, int capacity, AllocationType allocation,
Handle<AllocationSite> allocation_site) {
DCHECK(map->is_dictionary_map()); DCHECK(map->is_dictionary_map());
Handle<NameDictionary> object_properties = Handle<NameDictionary> object_properties =
NameDictionary::New(isolate(), capacity); NameDictionary::New(isolate(), capacity);
Handle<JSObject> js_object = NewJSObjectFromMap(map, allocation); Handle<JSObject> js_object =
NewJSObjectFromMap(map, allocation, allocation_site);
js_object->set_raw_properties_or_hash(*object_properties); js_object->set_raw_properties_or_hash(*object_properties);
return js_object; return js_object;
} }
......
...@@ -625,10 +625,19 @@ class V8_EXPORT_PRIVATE Factory { ...@@ -625,10 +625,19 @@ class V8_EXPORT_PRIVATE Factory {
Handle<JSObject> NewJSObjectFromMap( Handle<JSObject> NewJSObjectFromMap(
Handle<Map> map, AllocationType allocation = AllocationType::kYoung, Handle<Map> map, AllocationType allocation = AllocationType::kYoung,
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()); Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
// Like NewJSObjectFromMap, but includes allocating a properties dictionary.
Handle<JSObject> NewSlowJSObjectFromMap( Handle<JSObject> NewSlowJSObjectFromMap(
Handle<Map> map, Handle<Map> map,
int number_of_slow_properties = NameDictionary::kInitialCapacity, int number_of_slow_properties = NameDictionary::kInitialCapacity,
AllocationType allocation = AllocationType::kYoung); AllocationType allocation = AllocationType::kYoung,
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
// Calls NewJSObjectFromMap or NewSlowJSObjectFromMap depending on whether the
// map is a dictionary map.
inline Handle<JSObject> NewFastOrSlowJSObjectFromMap(
Handle<Map> map,
int number_of_slow_properties = NameDictionary::kInitialCapacity,
AllocationType allocation = AllocationType::kYoung,
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
// Allocates and initializes a new JavaScript object with the given // Allocates and initializes a new JavaScript object with the given
// {prototype} and {properties}. The newly created object will be // {prototype} and {properties}. The newly created object will be
// in dictionary properties mode. The {elements} can either be the // in dictionary properties mode. The {elements} can either be the
......
...@@ -114,11 +114,9 @@ JSListFormat::Type get_type(const char* str) { ...@@ -114,11 +114,9 @@ JSListFormat::Type get_type(const char* str) {
UNREACHABLE(); UNREACHABLE();
} }
MaybeHandle<JSListFormat> JSListFormat::Initialize( MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
Isolate* isolate, Handle<JSListFormat> list_format, Handle<Object> locales, Handle<Object> locales,
Handle<Object> input_options) { Handle<Object> input_options) {
list_format->set_flags(0);
Handle<JSReceiver> options; Handle<JSReceiver> options;
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
...@@ -156,11 +154,8 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize( ...@@ -156,11 +154,8 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
Intl::ResolvedLocale r = Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSListFormat::GetAvailableLocales(), Intl::ResolveLocale(isolate, JSListFormat::GetAvailableLocales(),
requested_locales, matcher, {}); requested_locales, matcher, {});
// 11. Set listFormat.[[Locale]] to r.[[Locale]].
Handle<String> locale_str = Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str()); isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
list_format->set_locale(*locale_str);
// 12. Let t be GetOption(options, "type", "string", «"conjunction", // 12. Let t be GetOption(options, "type", "string", «"conjunction",
// "disjunction", "unit"», "conjunction"). // "disjunction", "unit"», "conjunction").
...@@ -171,9 +166,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize( ...@@ -171,9 +166,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>()); MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>());
Type type_enum = maybe_type.FromJust(); Type type_enum = maybe_type.FromJust();
// 13. Set listFormat.[[Type]] to t.
list_format->set_type(type_enum);
// 14. Let s be ? GetOption(options, "style", "string", // 14. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long"). // «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>( Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
...@@ -182,9 +174,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize( ...@@ -182,9 +174,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>());
Style style_enum = maybe_style.FromJust(); Style style_enum = maybe_style.FromJust();
// 15. Set listFormat.[[Style]] to s.
list_format->set_style(style_enum);
icu::Locale icu_locale = r.icu_locale; icu::Locale icu_locale = r.icu_locale;
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
icu::ListFormatter* formatter = icu::ListFormatter::createInstance( icu::ListFormatter* formatter = icu::ListFormatter::createInstance(
...@@ -198,7 +187,22 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize( ...@@ -198,7 +187,22 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
Handle<Managed<icu::ListFormatter>> managed_formatter = Handle<Managed<icu::ListFormatter>> managed_formatter =
Managed<icu::ListFormatter>::FromRawPtr(isolate, 0, formatter); Managed<icu::ListFormatter>::FromRawPtr(isolate, 0, formatter);
// Now all properties are ready, so we can allocate the result object.
Handle<JSListFormat> list_format = Handle<JSListFormat>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
list_format->set_flags(0);
list_format->set_icu_formatter(*managed_formatter); list_format->set_icu_formatter(*managed_formatter);
// 11. Set listFormat.[[Locale]] to r.[[Locale]].
list_format->set_locale(*locale_str);
// 13. Set listFormat.[[Type]] to t.
list_format->set_type(type_enum);
// 15. Set listFormat.[[Style]] to s.
list_format->set_style(style_enum);
return list_format; return list_format;
} }
......
...@@ -30,11 +30,11 @@ namespace internal { ...@@ -30,11 +30,11 @@ namespace internal {
class JSListFormat : public JSObject { class JSListFormat : public JSObject {
public: public:
// Initializes relative time format object with properties derived from input // Creates relative time format object with properties derived from input
// locales and options. // locales and options.
static MaybeHandle<JSListFormat> Initialize( static MaybeHandle<JSListFormat> New(Isolate* isolate, Handle<Map> map,
Isolate* isolate, Handle<JSListFormat> list_format_holder, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options); Handle<Object> options);
static Handle<JSObject> ResolvedOptions(Isolate* isolate, static Handle<JSObject> ResolvedOptions(Isolate* isolate,
Handle<JSListFormat> format_holder); Handle<JSListFormat> format_holder);
......
...@@ -2003,13 +2003,9 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor, ...@@ -2003,13 +2003,9 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, initial_map, isolate, initial_map,
JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject); JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap( Handle<JSObject> result = isolate->factory()->NewFastOrSlowJSObjectFromMap(
initial_map, AllocationType::kYoung, site); initial_map, NameDictionary::kInitialCapacity, AllocationType::kYoung,
if (initial_map->is_dictionary_map()) { site);
Handle<NameDictionary> dictionary =
NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
result->SetProperties(*dictionary);
}
isolate->counters()->constructed_objects()->Increment(); isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment(); isolate->counters()->constructed_objects_runtime()->Increment();
return result; return result;
...@@ -2027,13 +2023,7 @@ MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate, ...@@ -2027,13 +2023,7 @@ MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype)); Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
// Actually allocate the object. // Actually allocate the object.
Handle<JSObject> object; return isolate->factory()->NewFastOrSlowJSObjectFromMap(map);
if (map->is_dictionary_map()) {
object = isolate->factory()->NewSlowJSObjectFromMap(map);
} else {
object = isolate->factory()->NewJSObjectFromMap(map);
}
return object;
} }
void JSObject::EnsureWritableFastElements(Handle<JSObject> object) { void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
......
...@@ -61,10 +61,9 @@ Handle<String> JSPluralRules::TypeAsString() const { ...@@ -61,10 +61,9 @@ Handle<String> JSPluralRules::TypeAsString() const {
} }
// static // static
MaybeHandle<JSPluralRules> JSPluralRules::Initialize( MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map,
Isolate* isolate, Handle<JSPluralRules> plural_rules, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options_obj) { Handle<Object> options_obj) {
plural_rules->set_flags(0);
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales); Intl::CanonicalizeLocaleList(isolate, locales);
...@@ -104,9 +103,6 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize( ...@@ -104,9 +103,6 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>()); MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>());
Type type = maybe_type.FromJust(); Type type = maybe_type.FromJust();
// 8. Set pluralRules.[[Type]] to t.
plural_rules->set_type(type);
// Note: The spec says we should do ResolveLocale after performing // Note: The spec says we should do ResolveLocale after performing
// SetNumberFormatDigitOptions but we need the locale to create all // SetNumberFormatDigitOptions but we need the locale to create all
// the ICU data structures. // the ICU data structures.
...@@ -119,11 +115,8 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize( ...@@ -119,11 +115,8 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
Intl::ResolvedLocale r = Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSPluralRules::GetAvailableLocales(), Intl::ResolveLocale(isolate, JSPluralRules::GetAvailableLocales(),
requested_locales, matcher, {}); requested_locales, matcher, {});
// 12. Set pluralRules.[[Locale]] to the value of r.[[locale]].
Handle<String> locale_str = Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str()); isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
plural_rules->set_locale(*locale_str);
icu::number::LocalizedNumberFormatter icu_number_formatter = icu::number::LocalizedNumberFormatter icu_number_formatter =
icu::number::NumberFormatter::withLocale(r.icu_locale) icu::number::NumberFormatter::withLocale(r.icu_locale)
...@@ -159,13 +152,26 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize( ...@@ -159,13 +152,26 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
Handle<Managed<icu::PluralRules>> managed_plural_rules = Handle<Managed<icu::PluralRules>> managed_plural_rules =
Managed<icu::PluralRules>::FromUniquePtr(isolate, 0, Managed<icu::PluralRules>::FromUniquePtr(isolate, 0,
std::move(icu_plural_rules)); std::move(icu_plural_rules));
plural_rules->set_icu_plural_rules(*managed_plural_rules);
Handle<Managed<icu::number::LocalizedNumberFormatter>> Handle<Managed<icu::number::LocalizedNumberFormatter>>
managed_number_formatter = managed_number_formatter =
Managed<icu::number::LocalizedNumberFormatter>::FromRawPtr( Managed<icu::number::LocalizedNumberFormatter>::FromRawPtr(
isolate, 0, isolate, 0,
new icu::number::LocalizedNumberFormatter(icu_number_formatter)); new icu::number::LocalizedNumberFormatter(icu_number_formatter));
// Now all properties are ready, so we can allocate the result object.
Handle<JSPluralRules> plural_rules = Handle<JSPluralRules>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
plural_rules->set_flags(0);
// 8. Set pluralRules.[[Type]] to t.
plural_rules->set_type(type);
// 12. Set pluralRules.[[Locale]] to the value of r.[[locale]].
plural_rules->set_locale(*locale_str);
plural_rules->set_icu_plural_rules(*managed_plural_rules);
plural_rules->set_icu_number_formatter(*managed_number_formatter); plural_rules->set_icu_number_formatter(*managed_number_formatter);
// 13. Return pluralRules. // 13. Return pluralRules.
......
...@@ -33,9 +33,9 @@ namespace internal { ...@@ -33,9 +33,9 @@ namespace internal {
class JSPluralRules : public JSObject { class JSPluralRules : public JSObject {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSPluralRules> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSPluralRules> New(
Isolate* isolate, Handle<JSPluralRules> plural_rules, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options); Handle<Object> options);
static Handle<JSObject> ResolvedOptions(Isolate* isolate, static Handle<JSObject> ResolvedOptions(Isolate* isolate,
Handle<JSPluralRules> plural_rules); Handle<JSPluralRules> plural_rules);
......
...@@ -54,11 +54,9 @@ JSRelativeTimeFormat::Numeric JSRelativeTimeFormat::getNumeric( ...@@ -54,11 +54,9 @@ JSRelativeTimeFormat::Numeric JSRelativeTimeFormat::getNumeric(
UNREACHABLE(); UNREACHABLE();
} }
MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
Isolate* isolate, Handle<JSRelativeTimeFormat> relative_time_format_holder, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> input_options) { Handle<Object> input_options) {
relative_time_format_holder->set_flags(0);
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales); Intl::CanonicalizeLocaleList(isolate, locales);
...@@ -125,7 +123,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( ...@@ -125,7 +123,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Handle<String> locale_str = isolate->factory()->NewStringFromAsciiChecked( Handle<String> locale_str = isolate->factory()->NewStringFromAsciiChecked(
maybe_locale_str.FromJust().c_str()); maybe_locale_str.FromJust().c_str());
relative_time_format_holder->set_locale(*locale_str);
// 15. Let s be ? GetOption(options, "style", "string", // 15. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long"). // «"long", "short", "narrow"», "long").
...@@ -136,9 +133,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( ...@@ -136,9 +133,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>());
Style style_enum = maybe_style.FromJust(); Style style_enum = maybe_style.FromJust();
// 16. Set relativeTimeFormat.[[Style]] to s.
relative_time_format_holder->set_style(style_enum);
// 17. Let numeric be ? GetOption(options, "numeric", "string", // 17. Let numeric be ? GetOption(options, "numeric", "string",
// «"always", "auto"», "always"). // «"always", "auto"», "always").
Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>( Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>(
...@@ -147,9 +141,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( ...@@ -147,9 +141,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>());
Numeric numeric_enum = maybe_numeric.FromJust(); Numeric numeric_enum = maybe_numeric.FromJust();
// 18. Set relativeTimeFormat.[[Numeric]] to numeric.
relative_time_format_holder->set_numeric(numeric_enum);
// 19. Let relativeTimeFormat.[[NumberFormat]] be // 19. Let relativeTimeFormat.[[NumberFormat]] be
// ? Construct(%NumberFormat%, « nfLocale, nfOptions »). // ? Construct(%NumberFormat%, « nfLocale, nfOptions »).
icu::NumberFormat* number_format = icu::NumberFormat* number_format =
...@@ -179,6 +170,21 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( ...@@ -179,6 +170,21 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Managed<icu::RelativeDateTimeFormatter>::FromRawPtr(isolate, 0, Managed<icu::RelativeDateTimeFormatter>::FromRawPtr(isolate, 0,
icu_formatter); icu_formatter);
// Now all properties are ready, so we can allocate the result object.
Handle<JSRelativeTimeFormat> relative_time_format_holder =
Handle<JSRelativeTimeFormat>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
relative_time_format_holder->set_flags(0);
relative_time_format_holder->set_locale(*locale_str);
// 16. Set relativeTimeFormat.[[Style]] to s.
relative_time_format_holder->set_style(style_enum);
// 18. Set relativeTimeFormat.[[Numeric]] to numeric.
relative_time_format_holder->set_numeric(numeric_enum);
// 21. Set relativeTimeFormat.[[InitializedRelativeTimeFormat]] to true. // 21. Set relativeTimeFormat.[[InitializedRelativeTimeFormat]] to true.
relative_time_format_holder->set_icu_formatter(*managed_formatter); relative_time_format_holder->set_icu_formatter(*managed_formatter);
......
...@@ -30,12 +30,11 @@ namespace internal { ...@@ -30,12 +30,11 @@ namespace internal {
class JSRelativeTimeFormat : public JSObject { class JSRelativeTimeFormat : public JSObject {
public: public:
// Initializes relative time format object with properties derived from input // Creates relative time format object with properties derived from input
// locales and options. // locales and options.
V8_WARN_UNUSED_RESULT static MaybeHandle<JSRelativeTimeFormat> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSRelativeTimeFormat> New(
Isolate* isolate, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<JSRelativeTimeFormat> relative_time_format_holder, Handle<Object> options);
Handle<Object> locales, Handle<Object> options);
V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions( V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSRelativeTimeFormat> format_holder); Isolate* isolate, Handle<JSRelativeTimeFormat> format_holder);
......
...@@ -30,11 +30,9 @@ JSSegmenter::Granularity JSSegmenter::GetGranularity(const char* str) { ...@@ -30,11 +30,9 @@ JSSegmenter::Granularity JSSegmenter::GetGranularity(const char* str) {
UNREACHABLE(); UNREACHABLE();
} }
MaybeHandle<JSSegmenter> JSSegmenter::Initialize( MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map,
Isolate* isolate, Handle<JSSegmenter> segmenter_holder, Handle<Object> locales,
Handle<Object> locales, Handle<Object> input_options) { Handle<Object> input_options) {
segmenter_holder->set_flags(0);
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales); Intl::CanonicalizeLocaleList(isolate, locales);
...@@ -69,11 +67,8 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize( ...@@ -69,11 +67,8 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
Intl::ResolvedLocale r = Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSSegmenter::GetAvailableLocales(), Intl::ResolveLocale(isolate, JSSegmenter::GetAvailableLocales(),
requested_locales, matcher, {}); requested_locales, matcher, {});
// 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
Handle<String> locale_str = Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str()); isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
segmenter_holder->set_locale(*locale_str);
// 13. Let granularity be ? GetOption(options, "granularity", "string", « // 13. Let granularity be ? GetOption(options, "granularity", "string", «
// "grapheme", "word", "sentence" », "grapheme"). // "grapheme", "word", "sentence" », "grapheme").
...@@ -85,9 +80,6 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize( ...@@ -85,9 +80,6 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
MAYBE_RETURN(maybe_granularity, MaybeHandle<JSSegmenter>()); MAYBE_RETURN(maybe_granularity, MaybeHandle<JSSegmenter>());
Granularity granularity_enum = maybe_granularity.FromJust(); Granularity granularity_enum = maybe_granularity.FromJust();
// 14. Set segmenter.[[SegmenterGranularity]] to granularity.
segmenter_holder->set_granularity(granularity_enum);
icu::Locale icu_locale = r.icu_locale; icu::Locale icu_locale = r.icu_locale;
DCHECK(!icu_locale.isBogus()); DCHECK(!icu_locale.isBogus());
...@@ -118,6 +110,18 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize( ...@@ -118,6 +110,18 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0, Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0,
std::move(icu_break_iterator)); std::move(icu_break_iterator));
// Now all properties are ready, so we can allocate the result object.
Handle<JSSegmenter> segmenter_holder = Handle<JSSegmenter>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
segmenter_holder->set_flags(0);
// 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
segmenter_holder->set_locale(*locale_str);
// 14. Set segmenter.[[SegmenterGranularity]] to granularity.
segmenter_holder->set_granularity(granularity_enum);
segmenter_holder->set_icu_break_iterator(*managed_break_iterator); segmenter_holder->set_icu_break_iterator(*managed_break_iterator);
return segmenter_holder; return segmenter_holder;
} }
......
...@@ -30,11 +30,11 @@ namespace internal { ...@@ -30,11 +30,11 @@ namespace internal {
class JSSegmenter : public JSObject { class JSSegmenter : public JSObject {
public: public:
// Initializes segmenter object with properties derived from input // Creates segmenter object with properties derived from input locales and
// locales and options. // options.
V8_WARN_UNUSED_RESULT static MaybeHandle<JSSegmenter> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSSegmenter> New(
Isolate* isolate, Handle<JSSegmenter> segmenter_holder, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options); Handle<Object> options);
V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions( V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSSegmenter> segmenter_holder); Isolate* isolate, Handle<JSSegmenter> segmenter_holder);
......
...@@ -351,10 +351,8 @@ struct ObjectLiteralHelper { ...@@ -351,10 +351,8 @@ struct ObjectLiteralHelper {
native_context, number_of_properties); native_context, number_of_properties);
Handle<JSObject> boilerplate = Handle<JSObject> boilerplate =
map->is_dictionary_map() isolate->factory()->NewFastOrSlowJSObjectFromMap(
? isolate->factory()->NewSlowJSObjectFromMap( map, number_of_properties, allocation);
map, number_of_properties, allocation)
: isolate->factory()->NewJSObjectFromMap(map, allocation);
// Normalize the elements of the boilerplate to save space if needed. // Normalize the elements of the boilerplate to save space if needed.
if (!use_fast_elements) JSObject::NormalizeElements(boilerplate); if (!use_fast_elements) JSObject::NormalizeElements(boilerplate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment