Skip to content
Permalink
Browse files
All prototypes should call didBecomePrototype()
https://bugs.webkit.org/show_bug.cgi?id=196315

Reviewed by Saam Barati.

JSTests:

* stress/function-prototype-indexed-accessor.js: Added.

Source/JavaScriptCore:

Otherwise we won't remember to run haveABadTime() when someone adds to them an indexed accessor.

I added a check used in both Structure::finishCreation() and Structure::changePrototypeTransition to make sure we don't
create structures with invalid prototypes.
It found a lot of objects that are used as prototypes in JSGlobalObject and yet were missing didBecomePrototype() in their finishCreation().
Somewhat surprisingly, some of them have names like FunctionConstructor and not only FooPrototype.

* runtime/BigIntPrototype.cpp:
(JSC::BigIntPrototype::finishCreation):
* runtime/BooleanPrototype.cpp:
(JSC::BooleanPrototype::finishCreation):
* runtime/DatePrototype.cpp:
(JSC::DatePrototype::finishCreation):
* runtime/ErrorConstructor.cpp:
(JSC::ErrorConstructor::finishCreation):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::finishCreation):
* runtime/FunctionConstructor.cpp:
(JSC::FunctionConstructor::finishCreation):
* runtime/FunctionPrototype.cpp:
(JSC::FunctionPrototype::finishCreation):
* runtime/IntlCollatorPrototype.cpp:
(JSC::IntlCollatorPrototype::finishCreation):
* runtime/IntlDateTimeFormatPrototype.cpp:
(JSC::IntlDateTimeFormatPrototype::finishCreation):
* runtime/IntlNumberFormatPrototype.cpp:
(JSC::IntlNumberFormatPrototype::finishCreation):
* runtime/IntlPluralRulesPrototype.cpp:
(JSC::IntlPluralRulesPrototype::finishCreation):
* runtime/JSArrayBufferPrototype.cpp:
(JSC::JSArrayBufferPrototype::finishCreation):
* runtime/JSDataViewPrototype.cpp:
(JSC::JSDataViewPrototype::finishCreation):
* runtime/JSGenericTypedArrayViewPrototypeInlines.h:
(JSC::JSGenericTypedArrayViewPrototype<ViewClass>::finishCreation):
* runtime/JSGlobalObject.cpp:
(JSC::createConsoleProperty):
* runtime/JSPromisePrototype.cpp:
(JSC::JSPromisePrototype::finishCreation):
* runtime/JSTypedArrayViewConstructor.cpp:
(JSC::JSTypedArrayViewConstructor::finishCreation):
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSTypedArrayViewPrototype::finishCreation):
* runtime/NumberPrototype.cpp:
(JSC::NumberPrototype::finishCreation):
* runtime/RegExpPrototype.cpp:
(JSC::RegExpPrototype::finishCreation):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
* runtime/Structure.cpp:
(JSC::Structure::isValidPrototype):
(JSC::Structure::changePrototypeTransition):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::setPrototypeWithoutTransition):
* runtime/SymbolPrototype.cpp:
(JSC::SymbolPrototype::finishCreation):
* wasm/js/WebAssemblyCompileErrorPrototype.cpp:
(JSC::WebAssemblyCompileErrorPrototype::finishCreation):
* wasm/js/WebAssemblyInstancePrototype.cpp:
(JSC::WebAssemblyInstancePrototype::finishCreation):
* wasm/js/WebAssemblyLinkErrorPrototype.cpp:
(JSC::WebAssemblyLinkErrorPrototype::finishCreation):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::WebAssemblyMemoryPrototype::finishCreation):
* wasm/js/WebAssemblyModulePrototype.cpp:
(JSC::WebAssemblyModulePrototype::finishCreation):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::WebAssemblyPrototype::finishCreation):
* wasm/js/WebAssemblyRuntimeErrorPrototype.cpp:
(JSC::WebAssemblyRuntimeErrorPrototype::finishCreation):
* wasm/js/WebAssemblyTablePrototype.cpp:
(JSC::WebAssemblyTablePrototype::finishCreation):

Source/WebCore:

* bindings/js/JSDOMIterator.h:
(WebCore::IteratorTraits>::finishCreation):
* bindings/js/JSDOMWindowProperties.h:
(WebCore::JSDOMWindowProperties::create): Deleted.
(WebCore::JSDOMWindowProperties::createStructure): Deleted.
(WebCore::JSDOMWindowProperties::JSDOMWindowProperties): Deleted.
* bindings/js/JSWindowProxy.cpp:
(WebCore::JSWindowProxy::setWindow):
* bindings/scripts/CodeGeneratorJS.pm:
(GeneratePrototypeDeclaration):
(GenerateConstructorHelperMethods):
* bindings/scripts/test/JS/JSInterfaceName.cpp:
(WebCore::JSInterfaceNamePrototype::JSInterfaceNamePrototype):
* bindings/scripts/test/JS/JSMapLike.cpp:
(WebCore::JSMapLikePrototype::JSMapLikePrototype):
* bindings/scripts/test/JS/JSReadOnlyMapLike.cpp:
(WebCore::JSReadOnlyMapLikePrototype::JSReadOnlyMapLikePrototype):
* bindings/scripts/test/JS/JSTestActiveDOMObject.cpp:
(WebCore::JSTestActiveDOMObjectPrototype::JSTestActiveDOMObjectPrototype):
* bindings/scripts/test/JS/JSTestCEReactions.cpp:
(WebCore::JSTestCEReactionsPrototype::JSTestCEReactionsPrototype):
* bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp:
(WebCore::JSTestCEReactionsStringifierPrototype::JSTestCEReactionsStringifierPrototype):
* bindings/scripts/test/JS/JSTestCallTracer.cpp:
(WebCore::JSTestCallTracerPrototype::JSTestCallTracerPrototype):
* bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp:
(WebCore::JSTestClassWithJSBuiltinConstructorPrototype::JSTestClassWithJSBuiltinConstructorPrototype):
* bindings/scripts/test/JS/JSTestDOMJIT.cpp:
(WebCore::JSTestDOMJITPrototype::JSTestDOMJITPrototype):
(WebCore::JSTestDOMJITConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestEnabledBySetting.cpp:
(WebCore::JSTestEnabledBySettingPrototype::JSTestEnabledBySettingPrototype):
* bindings/scripts/test/JS/JSTestEnabledForContext.cpp:
(WebCore::JSTestEnabledForContextPrototype::JSTestEnabledForContextPrototype):
* bindings/scripts/test/JS/JSTestEventConstructor.cpp:
(WebCore::JSTestEventConstructorPrototype::JSTestEventConstructorPrototype):
(WebCore::JSTestEventConstructorConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestEventTarget.cpp:
(WebCore::JSTestEventTargetPrototype::JSTestEventTargetPrototype):
(WebCore::JSTestEventTargetConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestException.cpp:
(WebCore::JSTestExceptionPrototype::JSTestExceptionPrototype):
* bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:
(WebCore::JSTestGenerateIsReachablePrototype::JSTestGenerateIsReachablePrototype):
* bindings/scripts/test/JS/JSTestGlobalObject.h:
(WebCore::JSTestGlobalObjectPrototype::JSTestGlobalObjectPrototype):
* bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp:
(WebCore::JSTestIndexedSetterNoIdentifierPrototype::JSTestIndexedSetterNoIdentifierPrototype):
* bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp:
(WebCore::JSTestIndexedSetterThrowingExceptionPrototype::JSTestIndexedSetterThrowingExceptionPrototype):
* bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp:
(WebCore::JSTestIndexedSetterWithIdentifierPrototype::JSTestIndexedSetterWithIdentifierPrototype):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfacePrototype::JSTestInterfacePrototype):
* bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp:
(WebCore::JSTestInterfaceLeadingUnderscorePrototype::JSTestInterfaceLeadingUnderscorePrototype):
* bindings/scripts/test/JS/JSTestIterable.cpp:
(WebCore::JSTestIterablePrototype::JSTestIterablePrototype):
* bindings/scripts/test/JS/JSTestJSBuiltinConstructor.cpp:
(WebCore::JSTestJSBuiltinConstructorPrototype::JSTestJSBuiltinConstructorPrototype):
* bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp:
(WebCore::JSTestMediaQueryListListenerPrototype::JSTestMediaQueryListListenerPrototype):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:
(WebCore::JSTestNamedAndIndexedSetterNoIdentifierPrototype::JSTestNamedAndIndexedSetterNoIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:
(WebCore::JSTestNamedAndIndexedSetterThrowingExceptionPrototype::JSTestNamedAndIndexedSetterThrowingExceptionPrototype):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:
(WebCore::JSTestNamedAndIndexedSetterWithIdentifierPrototype::JSTestNamedAndIndexedSetterWithIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
(WebCore::JSTestNamedConstructorPrototype::JSTestNamedConstructorPrototype):
* bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp:
(WebCore::JSTestNamedDeleterNoIdentifierPrototype::JSTestNamedDeleterNoIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp:
(WebCore::JSTestNamedDeleterThrowingExceptionPrototype::JSTestNamedDeleterThrowingExceptionPrototype):
* bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp:
(WebCore::JSTestNamedDeleterWithIdentifierPrototype::JSTestNamedDeleterWithIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp:
(WebCore::JSTestNamedDeleterWithIndexedGetterPrototype::JSTestNamedDeleterWithIndexedGetterPrototype):
* bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp:
(WebCore::JSTestNamedGetterCallWithPrototype::JSTestNamedGetterCallWithPrototype):
* bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp:
(WebCore::JSTestNamedGetterNoIdentifierPrototype::JSTestNamedGetterNoIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp:
(WebCore::JSTestNamedGetterWithIdentifierPrototype::JSTestNamedGetterWithIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:
(WebCore::JSTestNamedSetterNoIdentifierPrototype::JSTestNamedSetterNoIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:
(WebCore::JSTestNamedSetterThrowingExceptionPrototype::JSTestNamedSetterThrowingExceptionPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:
(WebCore::JSTestNamedSetterWithIdentifierPrototype::JSTestNamedSetterWithIdentifierPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:
(WebCore::JSTestNamedSetterWithIndexedGetterPrototype::JSTestNamedSetterWithIndexedGetterPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:
(WebCore::JSTestNamedSetterWithIndexedGetterAndSetterPrototype::JSTestNamedSetterWithIndexedGetterAndSetterPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.cpp:
(WebCore::JSTestNamedSetterWithOverrideBuiltinsPrototype::JSTestNamedSetterWithOverrideBuiltinsPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp:
(WebCore::JSTestNamedSetterWithUnforgablePropertiesPrototype::JSTestNamedSetterWithUnforgablePropertiesPrototype):
* bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.cpp:
(WebCore::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsPrototype::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsPrototype):
* bindings/scripts/test/JS/JSTestNode.cpp:
(WebCore::JSTestNodePrototype::JSTestNodePrototype):
(WebCore::JSTestNodeConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObjPrototype::JSTestObjPrototype):
* bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
(WebCore::JSTestOverloadedConstructorsPrototype::JSTestOverloadedConstructorsPrototype):
* bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp:
(WebCore::JSTestOverloadedConstructorsWithSequencePrototype::JSTestOverloadedConstructorsWithSequencePrototype):
* bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp:
(WebCore::JSTestOverrideBuiltinsPrototype::JSTestOverrideBuiltinsPrototype):
* bindings/scripts/test/JS/JSTestPluginInterface.cpp:
(WebCore::JSTestPluginInterfacePrototype::JSTestPluginInterfacePrototype):
* bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp:
(WebCore::JSTestPromiseRejectionEventPrototype::JSTestPromiseRejectionEventPrototype):
(WebCore::JSTestPromiseRejectionEventConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestSerialization.cpp:
(WebCore::JSTestSerializationPrototype::JSTestSerializationPrototype):
* bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.cpp:
(WebCore::JSTestSerializationIndirectInheritancePrototype::JSTestSerializationIndirectInheritancePrototype):
(WebCore::JSTestSerializationIndirectInheritanceConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestSerializationInherit.cpp:
(WebCore::JSTestSerializationInheritPrototype::JSTestSerializationInheritPrototype):
(WebCore::JSTestSerializationInheritConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestSerializationInheritFinal.cpp:
(WebCore::JSTestSerializationInheritFinalPrototype::JSTestSerializationInheritFinalPrototype):
(WebCore::JSTestSerializationInheritFinalConstructor::prototypeForStructure):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::JSTestSerializedScriptValueInterfacePrototype::JSTestSerializedScriptValueInterfacePrototype):
* bindings/scripts/test/JS/JSTestStringifier.cpp:
(WebCore::JSTestStringifierPrototype::JSTestStringifierPrototype):
* bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp:
(WebCore::JSTestStringifierAnonymousOperationPrototype::JSTestStringifierAnonymousOperationPrototype):
* bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp:
(WebCore::JSTestStringifierNamedOperationPrototype::JSTestStringifierNamedOperationPrototype):
* bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp:
(WebCore::JSTestStringifierOperationImplementedAsPrototype::JSTestStringifierOperationImplementedAsPrototype):
* bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp:
(WebCore::JSTestStringifierOperationNamedToStringPrototype::JSTestStringifierOperationNamedToStringPrototype):
* bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp:
(WebCore::JSTestStringifierReadOnlyAttributePrototype::JSTestStringifierReadOnlyAttributePrototype):
* bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp:
(WebCore::JSTestStringifierReadWriteAttributePrototype::JSTestStringifierReadWriteAttributePrototype):
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
(WebCore::JSTestTypedefsPrototype::JSTestTypedefsPrototype):

Canonical link: https://commits.webkit.org/213099@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246714 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Jun 22, 2019
1 parent d271669 commit 6be4bb89430ea87327992662e7ceea25b6a70cac
Show file tree
Hide file tree
Showing 104 changed files with 388 additions and 13 deletions.
@@ -1,3 +1,12 @@
2019-06-22 Robin Morisset <rmorisset@apple.com> and Yusuke Suzuki <ysuzuki@apple.com>

All prototypes should call didBecomePrototype()
https://bugs.webkit.org/show_bug.cgi?id=196315

Reviewed by Saam Barati.

* stress/function-prototype-indexed-accessor.js: Added.

2019-06-22 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Strict, Sloppy and Arrow functions should have different classInfo
@@ -0,0 +1,3 @@
Function[0] = 0;
Object.defineProperty(Function.__proto__, '42', { set: ()=>{} });
Function[1000] = 0;
@@ -1,3 +1,84 @@
2019-06-22 Robin Morisset <rmorisset@apple.com> and Yusuke Suzuki <ysuzuki@apple.com>

All prototypes should call didBecomePrototype()
https://bugs.webkit.org/show_bug.cgi?id=196315

Reviewed by Saam Barati.

Otherwise we won't remember to run haveABadTime() when someone adds to them an indexed accessor.

I added a check used in both Structure::finishCreation() and Structure::changePrototypeTransition to make sure we don't
create structures with invalid prototypes.
It found a lot of objects that are used as prototypes in JSGlobalObject and yet were missing didBecomePrototype() in their finishCreation().
Somewhat surprisingly, some of them have names like FunctionConstructor and not only FooPrototype.

* runtime/BigIntPrototype.cpp:
(JSC::BigIntPrototype::finishCreation):
* runtime/BooleanPrototype.cpp:
(JSC::BooleanPrototype::finishCreation):
* runtime/DatePrototype.cpp:
(JSC::DatePrototype::finishCreation):
* runtime/ErrorConstructor.cpp:
(JSC::ErrorConstructor::finishCreation):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::finishCreation):
* runtime/FunctionConstructor.cpp:
(JSC::FunctionConstructor::finishCreation):
* runtime/FunctionPrototype.cpp:
(JSC::FunctionPrototype::finishCreation):
* runtime/IntlCollatorPrototype.cpp:
(JSC::IntlCollatorPrototype::finishCreation):
* runtime/IntlDateTimeFormatPrototype.cpp:
(JSC::IntlDateTimeFormatPrototype::finishCreation):
* runtime/IntlNumberFormatPrototype.cpp:
(JSC::IntlNumberFormatPrototype::finishCreation):
* runtime/IntlPluralRulesPrototype.cpp:
(JSC::IntlPluralRulesPrototype::finishCreation):
* runtime/JSArrayBufferPrototype.cpp:
(JSC::JSArrayBufferPrototype::finishCreation):
* runtime/JSDataViewPrototype.cpp:
(JSC::JSDataViewPrototype::finishCreation):
* runtime/JSGenericTypedArrayViewPrototypeInlines.h:
(JSC::JSGenericTypedArrayViewPrototype<ViewClass>::finishCreation):
* runtime/JSGlobalObject.cpp:
(JSC::createConsoleProperty):
* runtime/JSPromisePrototype.cpp:
(JSC::JSPromisePrototype::finishCreation):
* runtime/JSTypedArrayViewConstructor.cpp:
(JSC::JSTypedArrayViewConstructor::finishCreation):
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSTypedArrayViewPrototype::finishCreation):
* runtime/NumberPrototype.cpp:
(JSC::NumberPrototype::finishCreation):
* runtime/RegExpPrototype.cpp:
(JSC::RegExpPrototype::finishCreation):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
* runtime/Structure.cpp:
(JSC::Structure::isValidPrototype):
(JSC::Structure::changePrototypeTransition):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::setPrototypeWithoutTransition):
* runtime/SymbolPrototype.cpp:
(JSC::SymbolPrototype::finishCreation):
* wasm/js/WebAssemblyCompileErrorPrototype.cpp:
(JSC::WebAssemblyCompileErrorPrototype::finishCreation):
* wasm/js/WebAssemblyInstancePrototype.cpp:
(JSC::WebAssemblyInstancePrototype::finishCreation):
* wasm/js/WebAssemblyLinkErrorPrototype.cpp:
(JSC::WebAssemblyLinkErrorPrototype::finishCreation):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::WebAssemblyMemoryPrototype::finishCreation):
* wasm/js/WebAssemblyModulePrototype.cpp:
(JSC::WebAssemblyModulePrototype::finishCreation):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::WebAssemblyPrototype::finishCreation):
* wasm/js/WebAssemblyRuntimeErrorPrototype.cpp:
(JSC::WebAssemblyRuntimeErrorPrototype::finishCreation):
* wasm/js/WebAssemblyTablePrototype.cpp:
(JSC::WebAssemblyTablePrototype::finishCreation):

2019-06-22 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Strict, Sloppy and Arrow functions should have different classInfo
@@ -73,6 +73,7 @@ void BigIntPrototype::finishCreation(VM& vm, JSGlobalObject*)
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "BigInt"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

// ------------------------------ Functions ---------------------------
@@ -59,6 +59,7 @@ void BooleanPrototype::finishCreation(VM& vm, JSGlobalObject*)
{
Base::finishCreation(vm);
setInternalValue(vm, jsBoolean(false));
didBecomePrototype();

ASSERT(inherits(vm, info()));
}
@@ -515,6 +515,7 @@ void DatePrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)

JSFunction* toPrimitiveFunction = JSFunction::create(vm, globalObject, 1, "[Symbol.toPrimitive]"_s, dateProtoFuncToPrimitiveSymbol, NoIntrinsic);
putDirectWithoutTransition(vm, vm.propertyNames->toPrimitiveSymbol, toPrimitiveFunction, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();

// The constructor will be added later, after DateConstructor has been built.
}
@@ -48,6 +48,7 @@ void ErrorConstructor::finishCreation(VM& vm, ErrorPrototype* errorPrototype)
putDirectWithoutTransition(vm, vm.propertyNames->prototype, errorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(globalObject(vm)->stackTraceLimit().valueOr(Options::defaultErrorStackTraceLimit())), static_cast<unsigned>(PropertyAttribute::None));
didBecomePrototype();
}

// ECMA 15.9.3
@@ -66,6 +66,7 @@ void ErrorPrototype::finishCreation(VM& vm, const String& name)
ASSERT(inherits(vm, info()));
putDirectWithoutTransition(vm, vm.propertyNames->name, jsString(&vm, name), static_cast<unsigned>(PropertyAttribute::DontEnum));
putDirectWithoutTransition(vm, vm.propertyNames->message, jsEmptyString(&vm), static_cast<unsigned>(PropertyAttribute::DontEnum));
didBecomePrototype();
}

// ------------------------------ Functions ---------------------------
@@ -61,6 +61,7 @@ void FunctionConstructor::finishCreation(VM& vm, FunctionPrototype* functionProt
Base::finishCreation(vm, vm.propertyNames->Function.string(), NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, functionPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
didBecomePrototype();
}

// ECMA 15.3.2 The Function Constructor
@@ -54,6 +54,7 @@ void FunctionPrototype::finishCreation(VM& vm, const String& name)
{
Base::finishCreation(vm, name, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
didBecomePrototype();
}

void FunctionPrototype::addFunctionProperties(VM& vm, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction, JSFunction** hasInstanceSymbolFunction)
@@ -76,6 +76,7 @@ void IntlCollatorPrototype::finishCreation(VM& vm)
Base::finishCreation(vm);

putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

static EncodedJSValue JSC_HOST_CALL IntlCollatorFuncCompare(ExecState* state)
@@ -90,6 +90,7 @@ void IntlDateTimeFormatPrototype::finishCreation(VM& vm, JSGlobalObject* globalO
#endif

putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

static EncodedJSValue JSC_HOST_CALL IntlDateTimeFormatFuncFormatDateTime(ExecState* state)
@@ -88,6 +88,7 @@ void IntlNumberFormatPrototype::finishCreation(VM& vm, JSGlobalObject* globalObj
#endif

putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

static EncodedJSValue JSC_HOST_CALL IntlNumberFormatFuncFormatNumber(ExecState* state)
@@ -75,6 +75,7 @@ void IntlPluralRulesPrototype::finishCreation(VM& vm, Structure*)
Base::finishCreation(vm);

putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

EncodedJSValue JSC_HOST_CALL IntlPluralRulesPrototypeFuncSelect(ExecState* state)
@@ -121,6 +121,7 @@ void JSArrayBufferPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject
JSC_NATIVE_GETTER_WITHOUT_TRANSITION(vm.propertyNames->byteLength, arrayBufferProtoGetterFuncByteLength, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
else
JSC_NATIVE_GETTER_WITHOUT_TRANSITION(vm.propertyNames->byteLength, sharedArrayBufferProtoGetterFuncByteLength, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

JSArrayBufferPrototype* JSArrayBufferPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure, ArrayBufferSharingMode sharingMode)
@@ -110,6 +110,7 @@ void JSDataViewPrototype::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "DataView"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

Structure* JSDataViewPrototype::createStructure(
@@ -45,6 +45,7 @@ void JSGenericTypedArrayViewPrototype<ViewClass>::finishCreation(

putDirect(vm, vm.propertyNames->BYTES_PER_ELEMENT, jsNumber(ViewClass::elementSize), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete);

didBecomePrototype();
}

template<typename ViewClass>
@@ -236,7 +236,9 @@ static JSValue createReflectProperty(VM& vm, JSObject* object)
static JSValue createConsoleProperty(VM& vm, JSObject* object)
{
JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
return ConsoleObject::create(vm, global, ConsoleObject::createStructure(vm, global, constructEmptyObject(global->globalExec())));
JSObject* prototype = constructEmptyObject(global->globalExec());
prototype->didBecomePrototype();
return ConsoleObject::create(vm, global, ConsoleObject::createStructure(vm, global, prototype));
}

static EncodedJSValue JSC_HOST_CALL makeBoundFunction(ExecState* exec)
@@ -77,6 +77,7 @@ void JSPromisePrototype::finishCreation(VM& vm, Structure*)
{
Base::finishCreation(vm);
putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Promise"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
didBecomePrototype();
}

void JSPromisePrototype::addOwnInternalSlots(VM& vm, JSGlobalObject* globalObject)
@@ -55,6 +55,8 @@ void JSTypedArrayViewConstructor::finishCreation(VM& vm, JSGlobalObject* globalO

JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->of, typedArrayConstructorOfCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->from, typedArrayConstructorFromCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));

didBecomePrototype();
}

Structure* JSTypedArrayViewConstructor::createStructure(
@@ -334,6 +334,7 @@ void JSTypedArrayViewPrototype::finishCreation(VM& vm, JSGlobalObject* globalObj
putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().valuesPublicName(), valuesFunction, static_cast<unsigned>(PropertyAttribute::DontEnum));
putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, valuesFunction, static_cast<unsigned>(PropertyAttribute::DontEnum));

didBecomePrototype();
}

JSTypedArrayViewPrototype* JSTypedArrayViewPrototype::create(
@@ -82,6 +82,7 @@ void NumberPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)

JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, numberProtoFuncToString, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, NumberPrototypeToStringIntrinsic);
ASSERT(inherits(vm, info()));
didBecomePrototype();
}

// ------------------------------ Functions ---------------------------
@@ -82,6 +82,8 @@ void RegExpPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpPrototypeSearchCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->splitSymbol, regExpPrototypeSplitCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpPrototypeTestCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));

didBecomePrototype();
}

// ------------------------------ Functions ---------------------------
@@ -173,6 +173,8 @@ void StringPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject, JSStr

// The constructor will be added later, after StringConstructor has been built
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);

didBecomePrototype();
}

StringPrototype* StringPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
@@ -321,6 +321,11 @@ Structure* Structure::create(PolyProtoTag, VM& vm, JSGlobalObject* globalObject,
return result;
}

bool Structure::isValidPrototype(JSValue prototype)
{
return prototype.isNull() || (prototype.isObject() && prototype.getObject()->mayBePrototype());
}

void Structure::findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*& structure, PropertyTable*& table)
{
ASSERT(structures.isEmpty());
@@ -544,7 +549,7 @@ Structure* Structure::removePropertyTransition(VM& vm, Structure* structure, Pro

Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype, DeferredStructureTransitionWatchpointFire& deferred)
{
ASSERT(prototype.isObject() || prototype.isNull());
ASSERT(isValidPrototype(prototype));

DeferGC deferGC(vm.heap);
Structure* transition = create(vm, structure, &deferred);
@@ -142,7 +142,7 @@ class Structure final : public JSCell {
void finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(m_prototype.get().isEmpty() || m_prototype.isObject() || m_prototype.isNull());
ASSERT(m_prototype.get().isEmpty() || isValidPrototype(m_prototype.get()));
}

void finishCreation(VM& vm, const Structure* previous)
@@ -680,6 +680,8 @@ class Structure final : public JSCell {

void checkConsistency();

JS_EXPORT_PRIVATE static bool isValidPrototype(JSValue);

// This may grab the lock, or not. Do not call when holding the Structure's lock.
PropertyTable* ensurePropertyTableIfNotEmpty(VM& vm)
{
@@ -493,6 +493,7 @@ inline PropertyOffset Structure::removePropertyWithoutTransition(VM&, PropertyNa

ALWAYS_INLINE void Structure::setPrototypeWithoutTransition(VM& vm, JSValue prototype)
{
ASSERT(isValidPrototype(prototype));
m_prototype.set(vm, this, prototype);
}

@@ -67,6 +67,8 @@ void SymbolPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)

JSFunction* toPrimitiveFunction = JSFunction::create(vm, globalObject, 1, "[Symbol.toPrimitive]"_s, symbolProtoFuncValueOf, NoIntrinsic);
putDirectWithoutTransition(vm, vm.propertyNames->toPrimitiveSymbol, toPrimitiveFunction, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);

didBecomePrototype();
}

// ------------------------------ Functions ---------------------------
@@ -57,6 +57,7 @@ Structure* WebAssemblyCompileErrorPrototype::createStructure(VM& vm, JSGlobalObj
void WebAssemblyCompileErrorPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
didBecomePrototype();
}

WebAssemblyCompileErrorPrototype::WebAssemblyCompileErrorPrototype(VM& vm, Structure* structure)
@@ -86,6 +86,7 @@ Structure* WebAssemblyInstancePrototype::createStructure(VM& vm, JSGlobalObject*