Commit 15ea19db authored by Seth Brenith's avatar Seth Brenith Committed by Commit Bot

[torque] Stricter object field verification, part 2

This change removes the special case in the Torque compiler for types
that descend from JSObject: they will no longer get implicit
"| Undefined" appended to their types for verification purposes. It
removes any additional custom verification steps in objects-debug that
are made redundant by that change.

In order to do so safely, I categorized all cases where we were
implicitly adding "| Undefined" to the field type, as follows:

1. Classes that aren't using the generated verifier function (we should
   probably revisit these, but for now we at least know they're safe):
   - JSGlobalObject
   - JSFinalizationGroup
   - JSFinalizationGroupCleanupIterator

2. Classes where the existing verifier is already at least as strict as
   what we would get after removing the implicit "| Undefined":
   - JSDate
   - JSPromise
   - JSRegExp
   - JSRegExpStringIterator
   - WasmMemoryObject
   - JSWeakRef
   - JSStringIterator
   - WasmExceptionObject
   - JSListFormat (fixed in part 1)
   - JSPluralRules (fixed in part 1)
   - JSRelativeTimeFormat (fixed in part 1)
   - JSSegmenter (fixed in part 1)
   - JSArrayBufferView (fixed in part 1)
   - JSTypedArray (fixed in part 1)

3. Classes where, to the best of my knowledge based on code inspection,
   we already initialize the object correctly to pass the new stricter
   generated verifier:
   - JSFunction
   - JSArrayIterator
   - JSMessageObject
   - JSBoundFunction
   - JSAsyncFromSyncIterator
   - WasmModuleObject
   - JSAsyncFunctionObject

4. Classes that needed some adjustment to their initialization order to
   avoid exposing uninitialized state to the GC:
   - JSArray (only in Factory::NewJSArray; Runtime_NewArray and
              CodeStubAssembler::AllocateJSArray already behave fine)
   - WasmTableObject
   - JSDateTimeFormat
   - JSNumberFormat
   - JSCollator
   - JSV8BreakIterator
   - JSLocale
   - JSSegmentIterator
   - JSModuleNamespace

5. Classes that had incorrect type definitions in Torque:
   - WasmGlobalObject (category 4 after correction)

6. Classes that weren't fully initialized due to bugs:
   - JSGeneratorObject
   - JSAsyncGeneratorObject

Bug: v8:9311
Change-Id: I99ab303d3352423f50a3d0abb6eb0c9b463e7552
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1654980
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62228}
parent f021c622
...@@ -565,7 +565,7 @@ extern class SharedFunctionInfo extends HeapObject { ...@@ -565,7 +565,7 @@ extern class SharedFunctionInfo extends HeapObject {
} }
extern class JSBoundFunction extends JSObject { extern class JSBoundFunction extends JSObject {
bound_target_function: JSReceiver; bound_target_function: Callable;
bound_this: Object; bound_this: Object;
bound_arguments: FixedArray; bound_arguments: FixedArray;
} }
...@@ -1313,8 +1313,8 @@ extern class WasmMemoryObject extends JSObject { ...@@ -1313,8 +1313,8 @@ extern class WasmMemoryObject extends JSObject {
} }
extern class WasmGlobalObject extends JSObject { extern class WasmGlobalObject extends JSObject {
untagged_buffer: JSArrayBuffer; untagged_buffer: JSArrayBuffer | Undefined;
tagged_buffer: FixedArray; tagged_buffer: FixedArray | Undefined;
offset: Smi; offset: Smi;
flags: Smi; flags: Smi;
} }
......
...@@ -276,15 +276,14 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, ...@@ -276,15 +276,14 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
// 2. Let format be ? OrdinaryCreateFromConstructor(newTarget, // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget,
// "%<T>Prototype%", ...). // "%<T>Prototype%", ...).
Handle<JSObject> obj; Handle<Map> map;
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> format = Handle<T>::cast(obj);
// 3. Perform ? Initialize<T>(Format, locales, options). // 3. Perform ? Initialize<T>(Format, locales, options).
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( Handle<T> format;
isolate, format, T::Initialize(isolate, format, locales, options)); ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, format,
T::New(isolate, map, locales, options));
// 4. Let this be the this value. // 4. Let this be the this value.
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
...@@ -383,14 +382,11 @@ Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) { ...@@ -383,14 +382,11 @@ Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) {
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);
Handle<JSObject> obj; Handle<Map> map;
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);
RETURN_RESULT_OR_FAILURE(isolate, RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options));
T::Initialize(isolate, result, locales, options));
} }
} // namespace } // namespace
...@@ -587,12 +583,11 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate, ...@@ -587,12 +583,11 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
Handle<JSFunction> constructor, Handle<JSFunction> constructor,
Handle<JSReceiver> new_target, Handle<JSReceiver> new_target,
Handle<Object> tag, Handle<Object> options) { Handle<Object> tag, Handle<Object> options) {
Handle<JSObject> locale; Handle<Map> map;
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget,
// %LocalePrototype%, internalSlotsList). // %LocalePrototype%, internalSlotsList).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, locale, isolate, map, JSFunction::GetDerivedMap(isolate, constructor, new_target),
JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
JSLocale); JSLocale);
// 7. If Type(tag) is not String or Object, throw a TypeError exception. // 7. If Type(tag) is not String or Object, throw a TypeError exception.
...@@ -624,8 +619,7 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate, ...@@ -624,8 +619,7 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
Object::ToObject(isolate, options), JSLocale); Object::ToObject(isolate, options), JSLocale);
} }
return JSLocale::Initialize(isolate, Handle<JSLocale>::cast(locale), return JSLocale::New(isolate, map, locale_string, options_object);
locale_string, options_object);
} }
} // namespace } // namespace
......
...@@ -1337,10 +1337,15 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { ...@@ -1337,10 +1337,15 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) {
StoreObjectFieldNoWriteBarrier( StoreObjectFieldNoWriteBarrier(
result, JSGeneratorObject::kParametersAndRegistersOffset, result, JSGeneratorObject::kParametersAndRegistersOffset,
parameters_and_registers); parameters_and_registers);
Node* resume_mode = SmiConstant(JSGeneratorObject::ResumeMode::kNext);
StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kResumeModeOffset,
resume_mode);
Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting); Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting);
StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kContinuationOffset, StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kContinuationOffset,
executing); executing);
GotoIfNot(HasInstanceType(maybe_map, JS_ASYNC_GENERATOR_OBJECT_TYPE), &done); GotoIfNot(InstanceTypeEqual(LoadMapInstanceType(maybe_map),
JS_ASYNC_GENERATOR_OBJECT_TYPE),
&done);
StoreObjectFieldNoWriteBarrier( StoreObjectFieldNoWriteBarrier(
result, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0)); result, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0));
Goto(&done); Goto(&done);
......
...@@ -837,7 +837,7 @@ Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) { ...@@ -837,7 +837,7 @@ Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
simplified()->LoadField(AccessBuilder::ForJSCollectionTable()), simplified()->LoadField(AccessBuilder::ForJSCollectionTable()),
iterated_object, effect, control); iterated_object, effect, control);
// Create the JSArrayIterator result. // Create the JSCollectionIterator result.
AllocationBuilder a(jsgraph(), effect, control); AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(JSCollectionIterator::kSize, AllocationType::kYoung, a.Allocate(JSCollectionIterator::kSize, AllocationType::kYoung,
Type::OtherObject()); Type::OtherObject());
......
...@@ -956,13 +956,7 @@ void JSDate::JSDateVerify(Isolate* isolate) { ...@@ -956,13 +956,7 @@ void JSDate::JSDateVerify(Isolate* isolate) {
} }
} }
void JSMessageObject::JSMessageObjectVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSMessageObject)
TorqueGeneratedClassVerifiers::JSMessageObjectVerify(*this, isolate);
VerifySmiField(kMessageTypeOffset);
VerifySmiField(kStartPositionOffset);
VerifySmiField(kEndPositionOffset);
VerifySmiField(kErrorLevelOffset);
}
USE_TORQUE_VERIFIER(Name) USE_TORQUE_VERIFIER(Name)
...@@ -1007,16 +1001,11 @@ USE_TORQUE_VERIFIER(ExternalString) ...@@ -1007,16 +1001,11 @@ USE_TORQUE_VERIFIER(ExternalString)
void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) { void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSBoundFunctionVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSBoundFunctionVerify(*this, isolate);
CHECK(IsCallable()); CHECK(IsCallable());
CHECK_EQ(IsConstructor(), bound_target_function().IsConstructor());
if (!raw_bound_target_function().IsUndefined(isolate)) {
CHECK(bound_target_function().IsCallable());
CHECK_EQ(IsConstructor(), bound_target_function().IsConstructor());
}
} }
void JSFunction::JSFunctionVerify(Isolate* isolate) { void JSFunction::JSFunctionVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSFunctionVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSFunctionVerify(*this, isolate);
CHECK(raw_feedback_cell().IsFeedbackCell());
CHECK(code().IsCode()); CHECK(code().IsCode());
CHECK(map().is_callable()); CHECK(map().is_callable());
Handle<JSFunction> function(*this, isolate); Handle<JSFunction> function(*this, isolate);
...@@ -1196,7 +1185,6 @@ void JSArray::JSArrayVerify(Isolate* isolate) { ...@@ -1196,7 +1185,6 @@ void JSArray::JSArrayVerify(Isolate* isolate) {
if (elements().length() == 0) { if (elements().length() == 0) {
CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array()); CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array());
} }
if (!length().IsNumber()) return;
// Verify that the length and the elements backing store are in sync. // Verify that the length and the elements backing store are in sync.
if (length().IsSmi() && (HasFastElements() || HasFrozenOrSealedElements())) { if (length().IsSmi() && (HasFastElements() || HasFrozenOrSealedElements())) {
if (elements().length() > 0) { if (elements().length() > 0) {
...@@ -1327,7 +1315,6 @@ void JSWeakMap::JSWeakMapVerify(Isolate* isolate) { ...@@ -1327,7 +1315,6 @@ void JSWeakMap::JSWeakMapVerify(Isolate* isolate) {
void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) { void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSArrayIteratorVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSArrayIteratorVerify(*this, isolate);
CHECK(iterated_object().IsJSReceiver());
CHECK_GE(next_index().Number(), 0); CHECK_GE(next_index().Number(), 0);
CHECK_LE(next_index().Number(), kMaxSafeInteger); CHECK_LE(next_index().Number(), kMaxSafeInteger);
...@@ -1344,8 +1331,6 @@ void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) { ...@@ -1344,8 +1331,6 @@ void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) {
void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) { void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSStringIteratorVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSStringIteratorVerify(*this, isolate);
CHECK(string().IsString());
CHECK_GE(index(), 0); CHECK_GE(index(), 0);
CHECK_LE(index(), String::kMaxLength); CHECK_LE(index(), String::kMaxLength);
} }
...@@ -1382,7 +1367,6 @@ USE_TORQUE_VERIFIER(PromiseReaction) ...@@ -1382,7 +1367,6 @@ USE_TORQUE_VERIFIER(PromiseReaction)
void JSPromise::JSPromiseVerify(Isolate* isolate) { void JSPromise::JSPromiseVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSPromiseVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSPromiseVerify(*this, isolate);
VerifySmiField(kFlagsOffset);
if (status() == Promise::kPending) { if (status() == Promise::kPending) {
CHECK(reactions().IsSmi() || reactions().IsPromiseReaction()); CHECK(reactions().IsSmi() || reactions().IsPromiseReaction());
} }
...@@ -1498,11 +1482,7 @@ void JSRegExp::JSRegExpVerify(Isolate* isolate) { ...@@ -1498,11 +1482,7 @@ void JSRegExp::JSRegExpVerify(Isolate* isolate) {
} }
} }
void JSRegExpStringIterator::JSRegExpStringIteratorVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSRegExpStringIterator)
TorqueGeneratedClassVerifiers::JSRegExpStringIteratorVerify(*this, isolate);
CHECK(iterating_string().IsString());
VerifySmiField(kFlagsOffset);
}
void JSProxy::JSProxyVerify(Isolate* isolate) { void JSProxy::JSProxyVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSProxyVerify(*this, isolate); TorqueGeneratedClassVerifiers::JSProxyVerify(*this, isolate);
...@@ -1527,7 +1507,6 @@ void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) { ...@@ -1527,7 +1507,6 @@ 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);
} }
...@@ -1687,31 +1666,15 @@ void WasmExportedFunctionData::WasmExportedFunctionDataVerify( ...@@ -1687,31 +1666,15 @@ void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
wrapper_code().kind() == Code::C_WASM_ENTRY); wrapper_code().kind() == Code::C_WASM_ENTRY);
} }
void WasmModuleObject::WasmModuleObjectVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(WasmModuleObject)
TorqueGeneratedClassVerifiers::WasmModuleObjectVerify(*this, isolate);
CHECK(managed_native_module().IsForeign());
CHECK(export_wrappers().IsFixedArray());
CHECK(script().IsScript());
}
void WasmTableObject::WasmTableObjectVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(WasmTableObject)
TorqueGeneratedClassVerifiers::WasmTableObjectVerify(*this, isolate);
CHECK(elements().IsFixedArray());
VerifySmiField(kRawTypeOffset);
}
void WasmMemoryObject::WasmMemoryObjectVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(WasmMemoryObject)
TorqueGeneratedClassVerifiers::WasmMemoryObjectVerify(*this, isolate);
CHECK(array_buffer().IsJSArrayBuffer());
VerifySmiField(kMaximumPagesOffset);
}
USE_TORQUE_VERIFIER(WasmGlobalObject) USE_TORQUE_VERIFIER(WasmGlobalObject)
void WasmExceptionObject::WasmExceptionObjectVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(WasmExceptionObject)
TorqueGeneratedClassVerifiers::WasmExceptionObjectVerify(*this, isolate);
CHECK(serialized_signature().IsByteArray());
}
void DataHandler::DataHandlerVerify(Isolate* isolate) { void DataHandler::DataHandlerVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::DataHandlerVerify(*this, isolate); TorqueGeneratedClassVerifiers::DataHandlerVerify(*this, isolate);
...@@ -1858,51 +1821,21 @@ USE_TORQUE_VERIFIER(JSV8BreakIterator) ...@@ -1858,51 +1821,21 @@ USE_TORQUE_VERIFIER(JSV8BreakIterator)
USE_TORQUE_VERIFIER(JSCollator) USE_TORQUE_VERIFIER(JSCollator)
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSDateTimeFormat)
TorqueGeneratedClassVerifiers::JSDateTimeFormatVerify(*this, isolate);
VerifySmiField(kFlagsOffset);
}
void JSListFormat::JSListFormatVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSListFormat)
TorqueGeneratedClassVerifiers::JSListFormatVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_formatter().IsForeign());
VerifySmiField(kFlagsOffset);
}
USE_TORQUE_VERIFIER(JSLocale) USE_TORQUE_VERIFIER(JSLocale)
void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSNumberFormat)
TorqueGeneratedClassVerifiers::JSNumberFormatVerify(*this, isolate);
VerifySmiField(kFlagsOffset);
}
void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSPluralRules)
TorqueGeneratedClassVerifiers::JSPluralRulesVerify(*this, isolate);
CHECK(locale().IsString());
VerifySmiField(kFlagsOffset);
CHECK(icu_plural_rules().IsForeign());
CHECK(icu_number_formatter().IsForeign());
}
void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSRelativeTimeFormat)
TorqueGeneratedClassVerifiers::JSRelativeTimeFormatVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_formatter().IsForeign());
VerifySmiField(kFlagsOffset);
}
void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSSegmentIterator)
TorqueGeneratedClassVerifiers::JSSegmentIteratorVerify(*this, isolate);
VerifySmiField(kFlagsOffset);
}
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(JSSegmenter)
TorqueGeneratedClassVerifiers::JSSegmenterVerify(*this, isolate);
CHECK(locale().IsString());
CHECK(icu_break_iterator().IsForeign());
VerifySmiField(kFlagsOffset);
}
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
......
...@@ -2925,37 +2925,48 @@ Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements( ...@@ -2925,37 +2925,48 @@ Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements(
return object; return object;
} }
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
AllocationType allocation) {
NativeContext native_context = isolate()->raw_native_context();
Map map = native_context.GetInitialJSArrayMap(elements_kind);
if (map.is_null()) {
JSFunction array_function = native_context.array_function();
map = array_function.initial_map();
}
return Handle<JSArray>::cast(
NewJSObjectFromMap(handle(map, isolate()), allocation));
}
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length, Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
int capacity, int capacity,
ArrayStorageAllocationMode mode, ArrayStorageAllocationMode mode,
AllocationType allocation) { AllocationType allocation) {
Handle<JSArray> array = NewJSArray(elements_kind, allocation); DCHECK(capacity >= length);
NewJSArrayStorage(array, length, capacity, mode); if (capacity == 0) {
return array; return NewJSArrayWithElements(empty_fixed_array(), elements_kind, length,
allocation);
}
HandleScope inner_scope(isolate());
Handle<FixedArrayBase> elms =
NewJSArrayStorage(elements_kind, capacity, mode);
return inner_scope.CloseAndEscape(NewJSArrayWithUnverifiedElements(
elms, elements_kind, length, allocation));
} }
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
ElementsKind elements_kind, ElementsKind elements_kind,
int length, int length,
AllocationType allocation) { AllocationType allocation) {
DCHECK(length <= elements->length()); Handle<JSArray> array = NewJSArrayWithUnverifiedElements(
Handle<JSArray> array = NewJSArray(elements_kind, allocation); elements, elements_kind, length, allocation);
JSObject::ValidateElements(*array);
return array;
}
Handle<JSArray> Factory::NewJSArrayWithUnverifiedElements(
Handle<FixedArrayBase> elements, ElementsKind elements_kind, int length,
AllocationType allocation) {
DCHECK(length <= elements->length());
NativeContext native_context = isolate()->raw_native_context();
Map map = native_context.GetInitialJSArrayMap(elements_kind);
if (map.is_null()) {
JSFunction array_function = native_context.array_function();
map = array_function.initial_map();
}
Handle<JSArray> array = Handle<JSArray>::cast(
NewJSObjectFromMap(handle(map, isolate()), allocation));
DisallowHeapAllocation no_gc;
array->set_elements(*elements); array->set_elements(*elements);
array->set_length(Smi::FromInt(length)); array->set_length(Smi::FromInt(length));
JSObject::ValidateElements(*array);
return array; return array;
} }
...@@ -2970,8 +2981,17 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, int length, int capacity, ...@@ -2970,8 +2981,17 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, int length, int capacity,
} }
HandleScope inner_scope(isolate()); HandleScope inner_scope(isolate());
Handle<FixedArrayBase> elms =
NewJSArrayStorage(array->GetElementsKind(), capacity, mode);
array->set_elements(*elms);
array->set_length(Smi::FromInt(length));
}
Handle<FixedArrayBase> Factory::NewJSArrayStorage(
ElementsKind elements_kind, int capacity, ArrayStorageAllocationMode mode) {
DCHECK_GT(capacity, 0);
Handle<FixedArrayBase> elms; Handle<FixedArrayBase> elms;
ElementsKind elements_kind = array->GetElementsKind();
if (IsDoubleElementsKind(elements_kind)) { if (IsDoubleElementsKind(elements_kind)) {
if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
elms = NewFixedDoubleArray(capacity); elms = NewFixedDoubleArray(capacity);
...@@ -2988,9 +3008,7 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, int length, int capacity, ...@@ -2988,9 +3008,7 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, int length, int capacity,
elms = NewFixedArrayWithHoles(capacity); elms = NewFixedArrayWithHoles(capacity);
} }
} }
return elms;
array->set_elements(*elms);
array->set_length(Smi::FromInt(length));
} }
Handle<JSWeakMap> Factory::NewJSWeakMap() { Handle<JSWeakMap> Factory::NewJSWeakMap() {
......
...@@ -1083,11 +1083,20 @@ class V8_EXPORT_PRIVATE Factory { ...@@ -1083,11 +1083,20 @@ class V8_EXPORT_PRIVATE Factory {
Handle<String> NumberToStringCacheSet(Handle<Object> number, int hash, Handle<String> NumberToStringCacheSet(Handle<Object> number, int hash,
const char* string, bool check_cache); const char* string, bool check_cache);
// Create a JSArray with no elements and no length. // Creates a new JSArray with the given backing storage. Performs no
Handle<JSArray> NewJSArray( // verification of the backing storage because it may not yet be filled.
ElementsKind elements_kind, Handle<JSArray> NewJSArrayWithUnverifiedElements(
Handle<FixedArrayBase> elements, ElementsKind elements_kind, int length,
AllocationType allocation = AllocationType::kYoung); AllocationType allocation = AllocationType::kYoung);
// Creates the backing storage for a JSArray. This handle must be discarded
// before returning the JSArray reference to code outside Factory, which might
// decide to left-trim the backing store. To avoid unnecessary HandleScopes,
// this method requires capacity greater than zero.
Handle<FixedArrayBase> NewJSArrayStorage(
ElementsKind elements_kind, int capacity,
ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS);
Handle<SharedFunctionInfo> NewSharedFunctionInfo( Handle<SharedFunctionInfo> NewSharedFunctionInfo(
MaybeHandle<String> name, MaybeHandle<HeapObject> maybe_function_data, MaybeHandle<String> name, MaybeHandle<HeapObject> maybe_function_data,
int maybe_builtin_index, FunctionKind kind = kNormalFunction); int maybe_builtin_index, FunctionKind kind = kNormalFunction);
......
...@@ -177,12 +177,11 @@ const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat, ...@@ -177,12 +177,11 @@ const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat,
template <typename T> template <typename T>
MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor, MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor,
Handle<Object> locales, Handle<Object> options) { Handle<Object> locales, Handle<Object> options) {
Handle<JSObject> result; Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, isolate, map,
JSObject::New(constructor, constructor, Handle<AllocationSite>::null()), JSFunction::GetDerivedMap(isolate, constructor, constructor), T);
T); return T::New(isolate, map, locales, options);
return T::Initialize(isolate, Handle<T>::cast(result), locales, options);
} }
} // namespace } // namespace
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize( MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options_obj) { Handle<Object> options_obj) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
...@@ -96,8 +96,13 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize( ...@@ -96,8 +96,13 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
Handle<String> locale_str = Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str()); isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
break_iterator_holder->set_locale(*locale_str);
// Now all properties are ready, so we can allocate the result object.
Handle<JSV8BreakIterator> break_iterator_holder =
Handle<JSV8BreakIterator>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
break_iterator_holder->set_locale(*locale_str);
break_iterator_holder->set_type(type_enum); break_iterator_holder->set_type(type_enum);
break_iterator_holder->set_break_iterator(*managed_break_iterator); break_iterator_holder->set_break_iterator(*managed_break_iterator);
break_iterator_holder->set_unicode_string(*managed_unicode_string); break_iterator_holder->set_unicode_string(*managed_unicode_string);
......
...@@ -29,9 +29,9 @@ namespace internal { ...@@ -29,9 +29,9 @@ namespace internal {
class JSV8BreakIterator : public JSObject { class JSV8BreakIterator : public JSObject {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> New(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator, Isolate* isolate, Handle<Map> map, Handle<Object> input_locales,
Handle<Object> input_locales, Handle<Object> input_options); Handle<Object> input_options);
static Handle<JSObject> ResolvedOptions( static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator); Isolate* isolate, Handle<JSV8BreakIterator> break_iterator);
......
...@@ -239,10 +239,9 @@ void SetCaseFirstOption(icu::Collator* icu_collator, ...@@ -239,10 +239,9 @@ void SetCaseFirstOption(icu::Collator* icu_collator,
} // anonymous namespace } // anonymous namespace
// static // static
MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate, MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
Handle<JSCollator> collator, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options_obj) {
Handle<Object> options_obj) {
// 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);
...@@ -465,6 +464,11 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate, ...@@ -465,6 +464,11 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
Handle<Managed<icu::Collator>> managed_collator = Handle<Managed<icu::Collator>> managed_collator =
Managed<icu::Collator>::FromUniquePtr(isolate, 0, Managed<icu::Collator>::FromUniquePtr(isolate, 0,
std::move(icu_collator)); std::move(icu_collator));
// Now all properties are ready, so we can allocate the result object.
Handle<JSCollator> collator = Handle<JSCollator>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
collator->set_icu_collator(*managed_collator); collator->set_icu_collator(*managed_collator);
// 29. Return collator. // 29. Return collator.
......
...@@ -32,8 +32,8 @@ namespace internal { ...@@ -32,8 +32,8 @@ namespace internal {
class JSCollator : public JSObject { class JSCollator : public JSObject {
public: public:
// ecma402/#sec-initializecollator // ecma402/#sec-initializecollator
V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> New(
Isolate* isolate, Handle<JSCollator> collator, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options); Handle<Object> options);
// ecma402/#sec-intl.collator.prototype.resolvedoptions // ecma402/#sec-intl.collator.prototype.resolvedoptions
......
...@@ -681,17 +681,14 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime( ...@@ -681,17 +681,14 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
JSFunction::cast( JSFunction::cast(
isolate->context().native_context().intl_date_time_format_function()), isolate->context().native_context().intl_date_time_format_function()),
isolate); isolate);
Handle<JSObject> obj; Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, obj, isolate, map,
JSObject::New(constructor, constructor, Handle<AllocationSite>::null()), JSFunction::GetDerivedMap(isolate, constructor, constructor), String);
String);
Handle<JSDateTimeFormat> date_time_format; Handle<JSDateTimeFormat> date_time_format;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, date_time_format, isolate, date_time_format,
JSDateTimeFormat::Initialize(isolate, Handle<JSDateTimeFormat>::cast(obj), JSDateTimeFormat::New(isolate, map, locales, internal_options), String);
locales, internal_options),
String);
if (can_cache) { if (can_cache) {
isolate->set_icu_object_in_cache( isolate->set_icu_object_in_cache(
...@@ -1207,10 +1204,9 @@ class DateTimePatternGeneratorCache { ...@@ -1207,10 +1204,9 @@ class DateTimePatternGeneratorCache {
enum FormatMatcherOption { kBestFit, kBasic }; enum FormatMatcherOption { kBestFit, kBasic };
// ecma402/#sec-initializedatetimeformat // ecma402/#sec-initializedatetimeformat
MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> input_options) { Handle<Object> input_options) {
date_time_format->set_flags(0);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 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 =
...@@ -1398,7 +1394,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1398,7 +1394,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
} }
} }
} }
date_time_format->set_hour_cycle(hc);
DateTimeStyle date_style = DateTimeStyle::kUndefined; DateTimeStyle date_style = DateTimeStyle::kUndefined;
DateTimeStyle time_style = DateTimeStyle::kUndefined; DateTimeStyle time_style = DateTimeStyle::kUndefined;
...@@ -1418,9 +1413,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1418,9 +1413,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to // 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to
// dateStyle. // dateStyle.
date_style = maybe_date_style.FromJust(); date_style = maybe_date_style.FromJust();
if (date_style != DateTimeStyle::kUndefined) {
date_time_format->set_date_style(date_style);
}
// 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « // 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", «
// "full", "long", "medium", "short" »). // "full", "long", "medium", "short" »).
...@@ -1436,9 +1428,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1436,9 +1428,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to // 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to
// timeStyle. // timeStyle.
time_style = maybe_time_style.FromJust(); time_style = maybe_time_style.FromJust();
if (time_style != DateTimeStyle::kUndefined) {
date_time_format->set_time_style(time_style);
}
// 32. If dateStyle or timeStyle are not undefined, then // 32. If dateStyle or timeStyle are not undefined, then
if (date_style != DateTimeStyle::kUndefined || if (date_style != DateTimeStyle::kUndefined ||
...@@ -1512,7 +1501,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1512,7 +1501,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// g. If dateTimeFormat.[[Hour]] is not undefined, then // g. If dateTimeFormat.[[Hour]] is not undefined, then
if (!has_hour_option) { if (!has_hour_option) {
// h. Else, i. Set dateTimeFormat.[[HourCycle]] to undefined. // h. Else, i. Set dateTimeFormat.[[HourCycle]] to undefined.
date_time_format->set_hour_cycle(Intl::HourCycle::kUndefined); hc = Intl::HourCycle::kUndefined;
} }
} }
...@@ -1538,8 +1527,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1538,8 +1527,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
maybe_hour_cycle.FromJust() != Intl::HourCycle::kUndefined) { maybe_hour_cycle.FromJust() != Intl::HourCycle::kUndefined) {
auto hc_extension_it = r.extensions.find("hc"); auto hc_extension_it = r.extensions.find("hc");
if (hc_extension_it != r.extensions.end()) { if (hc_extension_it != r.extensions.end()) {
if (date_time_format->hour_cycle() != if (hc != Intl::ToHourCycle(hc_extension_it->second.c_str())) {
Intl::ToHourCycle(hc_extension_it->second.c_str())) {
// Remove -hc- if it does not agree with what we used. // Remove -hc- if it does not agree with what we used.
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
icu_locale.setUnicodeKeywordValue("hc", nullptr, status); icu_locale.setUnicodeKeywordValue("hc", nullptr, status);
...@@ -1551,16 +1539,28 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -1551,16 +1539,28 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
Handle<Managed<icu::Locale>> managed_locale = Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone()); Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone());
date_time_format->set_icu_locale(*managed_locale);
Handle<Managed<icu::SimpleDateFormat>> managed_format = Handle<Managed<icu::SimpleDateFormat>> managed_format =
Managed<icu::SimpleDateFormat>::FromUniquePtr(isolate, 0, Managed<icu::SimpleDateFormat>::FromUniquePtr(isolate, 0,
std::move(icu_date_format)); std::move(icu_date_format));
date_time_format->set_icu_simple_date_format(*managed_format);
Handle<Managed<icu::DateIntervalFormat>> managed_interval_format = Handle<Managed<icu::DateIntervalFormat>> managed_interval_format =
Managed<icu::DateIntervalFormat>::FromRawPtr(isolate, 0, nullptr); Managed<icu::DateIntervalFormat>::FromRawPtr(isolate, 0, nullptr);
date_time_format->set_icu_date_interval_format(*managed_interval_format);
// Now all properties are ready, so we can allocate the result object.
Handle<JSDateTimeFormat> date_time_format = Handle<JSDateTimeFormat>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
date_time_format->set_flags(0);
date_time_format->set_hour_cycle(hc);
if (date_style != DateTimeStyle::kUndefined) {
date_time_format->set_date_style(date_style);
}
if (time_style != DateTimeStyle::kUndefined) {
date_time_format->set_time_style(time_style);
}
date_time_format->set_icu_locale(*managed_locale);
date_time_format->set_icu_simple_date_format(*managed_format);
date_time_format->set_icu_date_interval_format(*managed_interval_format);
return date_time_format; return date_time_format;
} }
......
...@@ -32,9 +32,9 @@ namespace internal { ...@@ -32,9 +32,9 @@ namespace internal {
class JSDateTimeFormat : public JSObject { class JSDateTimeFormat : public JSObject {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> New(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options); Handle<Object> options);
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions( V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format); Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
......
...@@ -313,10 +313,9 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, ...@@ -313,10 +313,9 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
} // namespace } // namespace
MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate, MaybeHandle<JSLocale> JSLocale::New(Isolate* isolate, Handle<Map> map,
Handle<JSLocale> locale, Handle<String> locale_str,
Handle<String> locale_str, Handle<JSReceiver> options) {
Handle<JSReceiver> options) {
icu::LocaleBuilder builder; icu::LocaleBuilder builder;
Maybe<bool> maybe_apply = Maybe<bool> maybe_apply =
ApplyOptionsToTag(isolate, locale_str, options, &builder); ApplyOptionsToTag(isolate, locale_str, options, &builder);
...@@ -341,8 +340,12 @@ MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate, ...@@ -341,8 +340,12 @@ MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate,
// 31. Set locale.[[Locale]] to r.[[locale]]. // 31. Set locale.[[Locale]] to r.[[locale]].
Handle<Managed<icu::Locale>> managed_locale = Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone()); Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone());
locale->set_icu_locale(*managed_locale);
// Now all properties are ready, so we can allocate the result object.
Handle<JSLocale> locale = Handle<JSLocale>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
locale->set_icu_locale(*managed_locale);
return locale; return locale;
} }
......
...@@ -27,12 +27,11 @@ namespace internal { ...@@ -27,12 +27,11 @@ namespace internal {
class JSLocale : public JSObject { class JSLocale : public JSObject {
public: public:
// Initializes locale object with properties derived from input locale string // Creates locale object with properties derived from input locale string
// and options. // and options.
static MaybeHandle<JSLocale> Initialize(Isolate* isolate, static MaybeHandle<JSLocale> New(Isolate* isolate, Handle<Map> map,
Handle<JSLocale> locale_holder, Handle<String> locale,
Handle<String> locale, Handle<JSReceiver> options);
Handle<JSReceiver> options);
static Handle<String> Maximize(Isolate* isolate, String locale); static Handle<String> Maximize(Isolate* isolate, String locale);
static Handle<String> Minimize(Isolate* isolate, String locale); static Handle<String> Minimize(Isolate* isolate, String locale);
......
...@@ -851,10 +851,10 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::UnwrapNumberFormat( ...@@ -851,10 +851,10 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::UnwrapNumberFormat(
} }
// static // static
MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
Isolate* isolate, Handle<JSNumberFormat> number_format, Handle<Map> map,
Handle<Object> locales, Handle<Object> options_obj) { Handle<Object> locales,
number_format->set_flags(0); Handle<Object> options_obj) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
...@@ -922,7 +922,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -922,7 +922,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 9. Set numberFormat.[[Locale]] to r.[[locale]]. // 9. Set numberFormat.[[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());
number_format->set_locale(*locale_str);
// 11. Let dataLocale be r.[[dataLocale]]. // 11. Let dataLocale be r.[[dataLocale]].
...@@ -1154,24 +1153,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -1154,24 +1153,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
icu_number_formatter = JSNumberFormat::SetDigitOptionsToFormatter( icu_number_formatter = JSNumberFormat::SetDigitOptionsToFormatter(
icu_number_formatter, digit_options); icu_number_formatter, digit_options);
if (digit_options.minimum_significant_digits > 0) {
// Currenct ECMA 402 spec mandate to record (Min|Max)imumFractionDigits
// uncondictionally while the unified number proposal eventually will only
// record either (Min|Max)imumFractionDigits or
// (Min|Max)imumSignaficantDigits Since LocalizedNumberFormatter can only
// remember one set, and during 2019-1-17 ECMA402 meeting that the committee
// decide not to take a PR to address that prior to the unified number
// proposal, we have to add these two 5 bits int into flags to remember the
// (Min|Max)imumFractionDigits while (Min|Max)imumSignaficantDigits is
// present.
// TODO(ftang) remove the following two lines once we ship
// int-number-format-unified
number_format->set_minimum_fraction_digits(
digit_options.minimum_fraction_digits);
number_format->set_maximum_fraction_digits(
digit_options.maximum_fraction_digits);
}
if (FLAG_harmony_intl_numberformat_unified) { if (FLAG_harmony_intl_numberformat_unified) {
// Let notation be ? GetOption(options, "notation", "string", « "standard", // Let notation be ? GetOption(options, "notation", "string", « "standard",
// "scientific", "engineering", "compact" », "standard"). // "scientific", "engineering", "compact" », "standard").
...@@ -1254,6 +1235,32 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -1254,6 +1235,32 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
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<JSNumberFormat> number_format = Handle<JSNumberFormat>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
number_format->set_flags(0);
number_format->set_locale(*locale_str);
if (digit_options.minimum_significant_digits > 0) {
// The current ECMA 402 spec mandates recording (Min|Max)imumFractionDigits
// unconditionally, while the unified number proposal eventually will only
// record either (Min|Max)imumFractionDigits or
// (Min|Max)imumSignificantDigits. Since LocalizedNumberFormatter can only
// remember one set, and during 2019-1-17 ECMA402 meeting the committee
// decided not to take a PR to address that prior to the unified number
// proposal, we have to add these two 5-bit ints into flags to remember the
// (Min|Max)imumFractionDigits while (Min|Max)imumSignificantDigits is
// present.
// TODO(ftang) remove the following two lines once we ship
// int-number-format-unified
number_format->set_minimum_fraction_digits(
digit_options.minimum_fraction_digits);
number_format->set_maximum_fraction_digits(
digit_options.maximum_fraction_digits);
}
number_format->set_icu_number_formatter(*managed_number_formatter); number_format->set_icu_number_formatter(*managed_number_formatter);
number_format->set_bound_format(*factory->undefined_value()); number_format->set_bound_format(*factory->undefined_value());
......
...@@ -34,9 +34,9 @@ namespace internal { ...@@ -34,9 +34,9 @@ namespace internal {
class JSNumberFormat : public JSObject { class JSNumberFormat : public JSObject {
public: public:
// ecma402/#sec-initializenumberformat // ecma402/#sec-initializenumberformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> Initialize( V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New(
Isolate* isolate, Handle<JSNumberFormat> number_format, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> locales, Handle<Object> options); Handle<Object> options);
// ecma402/#sec-unwrapnumberformat // ecma402/#sec-unwrapnumberformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat( V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat(
......
...@@ -445,10 +445,6 @@ void JSObject::InitializeBody(Map map, int start_offset, ...@@ -445,10 +445,6 @@ void JSObject::InitializeBody(Map map, int start_offset,
} }
} }
Object JSBoundFunction::raw_bound_target_function() const {
return READ_FIELD(*this, kBoundTargetFunctionOffset);
}
ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver, ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
kBoundTargetFunctionOffset) kBoundTargetFunctionOffset)
ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset) ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
......
...@@ -919,7 +919,6 @@ class JSIteratorResult : public JSObject { ...@@ -919,7 +919,6 @@ class JSIteratorResult : public JSObject {
class JSBoundFunction : public JSObject { class JSBoundFunction : public JSObject {
public: public:
// [bound_target_function]: The wrapped function object. // [bound_target_function]: The wrapped function object.
inline Object raw_bound_target_function() const;
DECL_ACCESSORS(bound_target_function, JSReceiver) DECL_ACCESSORS(bound_target_function, JSReceiver)
// [bound_this]: The value that is always passed as the this value when // [bound_this]: The value that is always passed as the this value when
......
...@@ -49,21 +49,24 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create( ...@@ -49,21 +49,24 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
// 1. Let iterator be ObjectCreate(%SegmentIteratorPrototype%). // 1. Let iterator be ObjectCreate(%SegmentIteratorPrototype%).
Handle<Map> map = Handle<Map>( Handle<Map> map = Handle<Map>(
isolate->native_context()->intl_segment_iterator_map(), isolate); isolate->native_context()->intl_segment_iterator_map(), isolate);
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
Managed<icu::UnicodeString> unicode_string =
Intl::SetTextToBreakIterator(isolate, text, break_iterator);
// Now all properties are ready, so we can allocate the result object.
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
DisallowHeapAllocation no_gc;
Handle<JSSegmentIterator> segment_iterator = Handle<JSSegmentIterator> segment_iterator =
Handle<JSSegmentIterator>::cast(result); Handle<JSSegmentIterator>::cast(result);
segment_iterator->set_flags(0); segment_iterator->set_flags(0);
segment_iterator->set_granularity(granularity); segment_iterator->set_granularity(granularity);
// 2. Let iterator.[[SegmentIteratorSegmenter]] be segmenter. // 2. Let iterator.[[SegmentIteratorSegmenter]] be segmenter.
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
segment_iterator->set_icu_break_iterator(*managed_break_iterator); segment_iterator->set_icu_break_iterator(*managed_break_iterator);
// 3. Let iterator.[[SegmentIteratorString]] be string. // 3. Let iterator.[[SegmentIteratorString]] be string.
Managed<icu::UnicodeString> unicode_string =
Intl::SetTextToBreakIterator(isolate, text, break_iterator);
segment_iterator->set_unicode_string(unicode_string); segment_iterator->set_unicode_string(unicode_string);
// 4. Let iterator.[[SegmentIteratorIndex]] be 0. // 4. Let iterator.[[SegmentIteratorIndex]] be 0.
......
...@@ -65,6 +65,7 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { ...@@ -65,6 +65,7 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
generator->set_context(isolate->context()); generator->set_context(isolate->context());
generator->set_receiver(*receiver); generator->set_receiver(*receiver);
generator->set_parameters_and_registers(*parameters_and_registers); generator->set_parameters_and_registers(*parameters_and_registers);
generator->set_resume_mode(JSGeneratorObject::ResumeMode::kNext);
generator->set_continuation(JSGeneratorObject::kGeneratorExecuting); generator->set_continuation(JSGeneratorObject::kGeneratorExecuting);
if (generator->IsJSAsyncGeneratorObject()) { if (generator->IsJSAsyncGeneratorObject()) {
Handle<JSAsyncGeneratorObject>::cast(generator)->set_is_awaiting(0); Handle<JSAsyncGeneratorObject>::cast(generator)->set_is_awaiting(0);
......
...@@ -3403,16 +3403,6 @@ void GenerateClassFieldVerifier(const std::string& class_name, ...@@ -3403,16 +3403,6 @@ void GenerateClassFieldVerifier(const std::string& class_name,
if (!type_check.empty()) type_check += " || "; if (!type_check.empty()) type_check += " || ";
type_check += strong_value + ".Is" + runtime_type + "()"; type_check += strong_value + ".Is" + runtime_type + "()";
} }
// Many subtypes of JSObject can be verified in partially-initialized states
// where their fields are all undefined. We explicitly allow that here. For
// any such fields that should never be undefined, we can include extra code
// in the custom verifier functions for them.
// TODO(1240798): If Factory::InitializeJSObjectFromMap is updated to use
// correct initial values based on the type of the field, then make this
// check stricter too.
if (class_type.IsSubtypeOf(TypeOracle::GetJSObjectType())) {
type_check += " || " + strong_value + ".IsUndefined(isolate)";
}
cc_contents << " CHECK(" << type_check << ");\n"; cc_contents << " CHECK(" << type_check << ");\n";
} }
cc_contents << " }\n"; cc_contents << " }\n";
......
...@@ -789,19 +789,21 @@ Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, ...@@ -789,19 +789,21 @@ Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate,
backing_store->set(i, null); backing_store->set(i, null);
} }
Handle<Object> max;
if (has_maximum) {
max = isolate->factory()->NewNumberFromUint(maximum);
} else {
max = isolate->factory()->undefined_value();
}
Handle<JSFunction> table_ctor( Handle<JSFunction> table_ctor(
isolate->native_context()->wasm_table_constructor(), isolate); isolate->native_context()->wasm_table_constructor(), isolate);
auto table_obj = Handle<WasmTableObject>::cast( auto table_obj = Handle<WasmTableObject>::cast(
isolate->factory()->NewJSObject(table_ctor)); isolate->factory()->NewJSObject(table_ctor));
DisallowHeapAllocation no_gc;
table_obj->set_raw_type(static_cast<int>(type)); table_obj->set_raw_type(static_cast<int>(type));
table_obj->set_entries(*backing_store); table_obj->set_entries(*backing_store);
Handle<Object> max;
if (has_maximum) {
max = isolate->factory()->NewNumberFromUint(maximum);
} else {
max = isolate->factory()->undefined_value();
}
table_obj->set_maximum_length(*max); table_obj->set_maximum_length(*max);
table_obj->set_dispatch_tables(ReadOnlyRoots(isolate).empty_fixed_array()); table_obj->set_dispatch_tables(ReadOnlyRoots(isolate).empty_fixed_array());
...@@ -1419,6 +1421,15 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New( ...@@ -1419,6 +1421,15 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New(
isolate->native_context()->wasm_global_constructor(), isolate); isolate->native_context()->wasm_global_constructor(), isolate);
auto global_obj = Handle<WasmGlobalObject>::cast( auto global_obj = Handle<WasmGlobalObject>::cast(
isolate->factory()->NewJSObject(global_ctor)); isolate->factory()->NewJSObject(global_ctor));
{
// Disallow GC until all fields have acceptable types.
DisallowHeapAllocation no_gc;
global_obj->set_flags(0);
global_obj->set_type(type);
global_obj->set_offset(offset);
global_obj->set_is_mutable(is_mutable);
}
if (wasm::ValueTypes::IsReferenceType(type)) { if (wasm::ValueTypes::IsReferenceType(type)) {
DCHECK(maybe_untagged_buffer.is_null()); DCHECK(maybe_untagged_buffer.is_null());
...@@ -1451,10 +1462,6 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New( ...@@ -1451,10 +1462,6 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New(
global_obj->set_untagged_buffer(*untagged_buffer); global_obj->set_untagged_buffer(*untagged_buffer);
} }
global_obj->set_flags(0);
global_obj->set_type(type);
global_obj->set_offset(offset);
global_obj->set_is_mutable(is_mutable);
return global_obj; return global_obj;
} }
......
...@@ -1654,6 +1654,15 @@ TEST(AllocateJSObjectFromMap) { ...@@ -1654,6 +1654,15 @@ TEST(AllocateJSObjectFromMap) {
Node* result = m.AllocateJSObjectFromMap(map, properties, elements); Node* result = m.AllocateJSObjectFromMap(map, properties, elements);
CodeStubAssembler::Label done(&m);
m.GotoIfNot(m.IsJSArrayMap(map), &done);
// JS array verification requires the length field to be set.
m.StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset,
m.SmiConstant(0));
m.Goto(&done);
m.Bind(&done);
m.Return(result); m.Return(result);
} }
......
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