[JSC] NativeErrorConstructor should not have own IsoSubspace
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Jan 2019 09:07:25 +0000 (09:07 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Jan 2019 09:07:25 +0000 (09:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193713

Reviewed by Saam Barati.

JSTests:

Remove @Error use.

* stress/try-get-by-id-should-spill-registers-dfg.js:
(let.f.createBuiltin):

Source/JavaScriptCore:

This removes an additional member in NativeErrorConstructor, and make sizeof(NativeErrorConstructor) == sizeof(InternalFunction).
We also make error constructors lazily allocated by using LazyClassStructure. Since error structures are not accessed from DFG / FTL
threads, this is OK. While TypeError constructor is eagerly allocated because it is touched from our builtin JS as @TypeError, we should
offer some function instead of exposing TypeError constructor in the future, and remove this @TypeError reference. This change removes
IsoSubspace for NativeErrorConstructor in VM. We also remove @Error and @RangeError references for builtins since they are no longer
referenced.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinNames.h:
* interpreter/Interpreter.h:
* runtime/Error.cpp:
(JSC::createEvalError):
(JSC::createRangeError):
(JSC::createReferenceError):
(JSC::createSyntaxError):
(JSC::createTypeError):
(JSC::createURIError):
(WTF::printInternal): Deleted.
* runtime/Error.h:
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::create):
(JSC::ErrorPrototype::finishCreation):
* runtime/ErrorPrototype.h:
(JSC::ErrorPrototype::create): Deleted.
* runtime/ErrorType.cpp: Added.
(JSC::errorTypeName):
(WTF::printInternal):
* runtime/ErrorType.h: Added.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::initializeErrorConstructor):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::internalPromiseConstructor const):
(JSC::JSGlobalObject::errorStructure const):
(JSC::JSGlobalObject::evalErrorConstructor const): Deleted.
(JSC::JSGlobalObject::rangeErrorConstructor const): Deleted.
(JSC::JSGlobalObject::referenceErrorConstructor const): Deleted.
(JSC::JSGlobalObject::syntaxErrorConstructor const): Deleted.
(JSC::JSGlobalObject::typeErrorConstructor const): Deleted.
(JSC::JSGlobalObject::URIErrorConstructor const): Deleted.
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor<errorType>::NativeErrorConstructor):
(JSC::NativeErrorConstructorBase::finishCreation):
(JSC::NativeErrorConstructor<errorType>::constructNativeErrorConstructor):
(JSC::NativeErrorConstructor<errorType>::callNativeErrorConstructor):
(JSC::NativeErrorConstructor::NativeErrorConstructor): Deleted.
(JSC::NativeErrorConstructor::finishCreation): Deleted.
(JSC::NativeErrorConstructor::visitChildren): Deleted.
(JSC::Interpreter::constructWithNativeErrorConstructor): Deleted.
(JSC::Interpreter::callNativeErrorConstructor): Deleted.
* runtime/NativeErrorConstructor.h:
(JSC::NativeErrorConstructorBase::createStructure):
(JSC::NativeErrorConstructorBase::NativeErrorConstructorBase):
* runtime/NativeErrorPrototype.cpp:
(JSC::NativeErrorPrototype::finishCreation): Deleted.
* runtime/NativeErrorPrototype.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::handleBadI64Use):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240543 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
JSTests/ChangeLog
JSTests/stress/try-get-by-id-should-spill-registers-dfg.js
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/builtins/BuiltinNames.h
Source/JavaScriptCore/interpreter/Interpreter.h
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/Error.h
Source/JavaScriptCore/runtime/ErrorPrototype.cpp
Source/JavaScriptCore/runtime/ErrorPrototype.h
Source/JavaScriptCore/runtime/ErrorType.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/ErrorType.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.h
Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
Source/JavaScriptCore/runtime/NativeErrorPrototype.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/js/WasmToJS.cpp

index 83028bb..4dc7172 100644 (file)
@@ -1,3 +1,15 @@
+2019-01-25  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] NativeErrorConstructor should not have own IsoSubspace
+        https://bugs.webkit.org/show_bug.cgi?id=193713
+
+        Reviewed by Saam Barati.
+
+        Remove @Error use.
+
+        * stress/try-get-by-id-should-spill-registers-dfg.js:
+        (let.f.createBuiltin):
+
 2019-01-24  Yusuke Suzuki  <ysuzuki@apple.com>
 
         stress/const-semantics.js fails a dfg-eager / ftl-eager run with an ASAN release build.
index 22507c1..c073814 100644 (file)
@@ -2,7 +2,7 @@ var createBuiltin = $vm.createBuiltin;
 
 let f = createBuiltin(`(function (arg) { 
     let r = @tryGetById(arg, "prototype");
-    if (arg !== true) throw new @Error("Bad clobber of arg");
+    if (arg !== true) throw new Error("Bad clobber of arg");
     return r;
 })`);
 noInline(f);
index de05300..7b43f3c 100644 (file)
@@ -772,6 +772,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
     runtime/ErrorHandlingScope.h
     runtime/ErrorInstance.h
     runtime/ErrorPrototype.h
+    runtime/ErrorType.h
     runtime/EvalExecutable.h
     runtime/Exception.h
     runtime/ExceptionEventLocation.h
index 253b1ea..3ac1016 100644 (file)
@@ -1,3 +1,75 @@
+2019-01-25  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] NativeErrorConstructor should not have own IsoSubspace
+        https://bugs.webkit.org/show_bug.cgi?id=193713
+
+        Reviewed by Saam Barati.
+
+        This removes an additional member in NativeErrorConstructor, and make sizeof(NativeErrorConstructor) == sizeof(InternalFunction).
+        We also make error constructors lazily allocated by using LazyClassStructure. Since error structures are not accessed from DFG / FTL
+        threads, this is OK. While TypeError constructor is eagerly allocated because it is touched from our builtin JS as @TypeError, we should
+        offer some function instead of exposing TypeError constructor in the future, and remove this @TypeError reference. This change removes
+        IsoSubspace for NativeErrorConstructor in VM. We also remove @Error and @RangeError references for builtins since they are no longer
+        referenced.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * builtins/BuiltinNames.h:
+        * interpreter/Interpreter.h:
+        * runtime/Error.cpp:
+        (JSC::createEvalError):
+        (JSC::createRangeError):
+        (JSC::createReferenceError):
+        (JSC::createSyntaxError):
+        (JSC::createTypeError):
+        (JSC::createURIError):
+        (WTF::printInternal): Deleted.
+        * runtime/Error.h:
+        * runtime/ErrorPrototype.cpp:
+        (JSC::ErrorPrototype::create):
+        (JSC::ErrorPrototype::finishCreation):
+        * runtime/ErrorPrototype.h:
+        (JSC::ErrorPrototype::create): Deleted.
+        * runtime/ErrorType.cpp: Added.
+        (JSC::errorTypeName):
+        (WTF::printInternal):
+        * runtime/ErrorType.h: Added.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::initializeErrorConstructor):
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::internalPromiseConstructor const):
+        (JSC::JSGlobalObject::errorStructure const):
+        (JSC::JSGlobalObject::evalErrorConstructor const): Deleted.
+        (JSC::JSGlobalObject::rangeErrorConstructor const): Deleted.
+        (JSC::JSGlobalObject::referenceErrorConstructor const): Deleted.
+        (JSC::JSGlobalObject::syntaxErrorConstructor const): Deleted.
+        (JSC::JSGlobalObject::typeErrorConstructor const): Deleted.
+        (JSC::JSGlobalObject::URIErrorConstructor const): Deleted.
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor<errorType>::NativeErrorConstructor):
+        (JSC::NativeErrorConstructorBase::finishCreation):
+        (JSC::NativeErrorConstructor<errorType>::constructNativeErrorConstructor):
+        (JSC::NativeErrorConstructor<errorType>::callNativeErrorConstructor):
+        (JSC::NativeErrorConstructor::NativeErrorConstructor): Deleted.
+        (JSC::NativeErrorConstructor::finishCreation): Deleted.
+        (JSC::NativeErrorConstructor::visitChildren): Deleted.
+        (JSC::Interpreter::constructWithNativeErrorConstructor): Deleted.
+        (JSC::Interpreter::callNativeErrorConstructor): Deleted.
+        * runtime/NativeErrorConstructor.h:
+        (JSC::NativeErrorConstructorBase::createStructure):
+        (JSC::NativeErrorConstructorBase::NativeErrorConstructorBase):
+        * runtime/NativeErrorPrototype.cpp:
+        (JSC::NativeErrorPrototype::finishCreation): Deleted.
+        * runtime/NativeErrorPrototype.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * wasm/js/WasmToJS.cpp:
+        (JSC::Wasm::handleBadI64Use):
+
 2019-01-25  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: provide a way to edit page settings on a remote target
index d5f115a..880eda2 100644 (file)
                E3C79CAB1DB9A4DC00D1ECA4 /* DOMJITEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C79CAA1DB9A4D600D1ECA4 /* DOMJITEffect.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3D239C91B829C1C00BBEF67 /* JSModuleEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3D877741E65C0A000BE945A /* BytecodeDumper.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D877721E65C08900BE945A /* BytecodeDumper.h */; };
+               E3EE137621FBD43500D83C4B /* ErrorType.h in Headers */ = {isa = PBXBuildFile; fileRef = E3EE137421FBD43400D83C4B /* ErrorType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3F23A7F1ECF13EE00978D99 /* SnippetSlowPathCalls.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F23A7E1ECF13E500978D99 /* SnippetSlowPathCalls.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3F23A801ECF13F500978D99 /* SnippetReg.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F23A7D1ECF13E500978D99 /* SnippetReg.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3F23A811ECF13FA00978D99 /* SnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F23A7C1ECF13E500978D99 /* SnippetParams.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E3D2642A1D38C042000BE174 /* BytecodeRewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeRewriter.h; sourceTree = "<group>"; };
                E3D877711E65C08900BE945A /* BytecodeDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeDumper.cpp; sourceTree = "<group>"; };
                E3D877721E65C08900BE945A /* BytecodeDumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeDumper.h; sourceTree = "<group>"; };
+               E3EE137421FBD43400D83C4B /* ErrorType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorType.h; sourceTree = "<group>"; };
+               E3EE137521FBD43400D83C4B /* ErrorType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorType.cpp; sourceTree = "<group>"; };
                E3F23A7B1ECF13E500978D99 /* Snippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Snippet.h; sourceTree = "<group>"; };
                E3F23A7C1ECF13E500978D99 /* SnippetParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetParams.h; sourceTree = "<group>"; };
                E3F23A7D1ECF13E500978D99 /* SnippetReg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetReg.h; sourceTree = "<group>"; };
                                BC02E98B0E183E38000F9297 /* ErrorInstance.h */,
                                BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */,
                                BC02E9070E1839DB000F9297 /* ErrorPrototype.h */,
+                               E3EE137521FBD43400D83C4B /* ErrorType.cpp */,
+                               E3EE137421FBD43400D83C4B /* ErrorType.h */,
                                147341DB1DC2CE9600AA29BA /* EvalExecutable.cpp */,
                                147341D11DC02E2E00AA29BA /* EvalExecutable.h */,
                                FE1C0FFE1B194FD100B53FCA /* Exception.cpp */,
                                BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
                                BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
                                996B731B1BDA08D100331B84 /* ErrorPrototype.lut.h in Headers */,
+                               E3EE137621FBD43500D83C4B /* ErrorType.h in Headers */,
                                14AD910C1DCA92940014F9FE /* EvalCodeBlock.h in Headers */,
                                147341D21DC02E2E00AA29BA /* EvalExecutable.h in Headers */,
                                A54982041891D0B00081E5B8 /* EventLoop.h in Headers */,
                                E3201C1D1F8E82360076A032 /* JSScriptFetchParameters.h in Headers */,
                                53EE01B8218F7EFF00AD1F8D /* JSScriptInternal.h in Headers */,
                                A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
+                               14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */,
                                0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
                                0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectHeapCellType.h in Headers */,
                                A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
                                14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
                                14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
                                14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
-                               14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */,
                                A7CA3AE417DA41AE006538AF /* WeakMapConstructor.h in Headers */,
                                E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */,
                                E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */,
index 258d49c..7a74608 100644 (file)
@@ -748,6 +748,7 @@ runtime/ErrorConstructor.cpp
 runtime/ErrorHandlingScope.cpp
 runtime/ErrorInstance.cpp
 runtime/ErrorPrototype.cpp
+runtime/ErrorType.cpp
 runtime/EvalExecutable.cpp
 runtime/Exception.cpp
 runtime/ExceptionEventLocation.cpp
index 8531db2..4a70144 100644 (file)
@@ -74,8 +74,6 @@ namespace JSC {
     macro(getOwnPropertyDescriptor) \
     macro(getOwnPropertyNames) \
     macro(ownKeys) \
-    macro(Error) \
-    macro(RangeError) \
     macro(Set) \
     macro(TypeError) \
     macro(typedArrayLength) \
index be5d5e9..394e535 100644 (file)
@@ -117,9 +117,6 @@ namespace JSC {
         NEVER_INLINE void debug(CallFrame*, DebugHookType);
         static String stackTraceAsString(VM&, const Vector<StackFrame>&);
 
-        static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*);
-        static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
-
         void getStackTrace(JSCell* owner, Vector<StackFrame>& results, size_t framesToSkip = 0, size_t maxStackSize = std::numeric_limits<size_t>::max());
 
     private:
index 1b8e4c2..9d78664 100644 (file)
@@ -53,7 +53,7 @@ JSObject* createEvalError(ExecState* exec, const String& message, ErrorInstance:
 {
     ASSERT(!message.isEmpty());
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, appender, TypeNothing, true);
 }
 
 JSObject* createRangeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
@@ -65,28 +65,28 @@ JSObject* createRangeError(ExecState* exec, const String& message, ErrorInstance
 JSObject* createRangeError(ExecState* exec, JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, appender, TypeNothing, true);
 }
 
 JSObject* createReferenceError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, appender, TypeNothing, true);
 }
 
 JSObject* createSyntaxError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, appender, TypeNothing, true);
 }
 
 JSObject* createTypeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
 {
     ASSERT(!message.isEmpty());
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message, appender, type, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, appender, type, true);
 }
 
 JSObject* createNotEnoughArgumentsError(ExecState* exec, ErrorInstance::SourceAppender appender)
@@ -98,7 +98,7 @@ JSObject* createURIError(ExecState* exec, const String& message, ErrorInstance::
 {
     ASSERT(!message.isEmpty());
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    return ErrorInstance::create(exec, globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, appender, TypeNothing, true);
 }
 
 JSObject* createError(ExecState* exec, ErrorType errorType, const String& message)
@@ -361,36 +361,3 @@ JSObject* createOutOfMemoryError(ExecState* exec, const String& message)
 }
 
 } // namespace JSC
-
-namespace WTF {
-
-using namespace JSC;
-
-void printInternal(PrintStream& out, JSC::ErrorType errorType)
-{
-    switch (errorType) {
-    case JSC::ErrorType::Error:
-        out.print("Error");
-        break;
-    case JSC::ErrorType::EvalError:
-        out.print("EvalError");
-        break;
-    case JSC::ErrorType::RangeError:
-        out.print("RangeError");
-        break;
-    case JSC::ErrorType::ReferenceError:
-        out.print("ReferenceError");
-        break;
-    case JSC::ErrorType::SyntaxError:
-        out.print("SyntaxError");
-        break;
-    case JSC::ErrorType::TypeError:
-        out.print("TypeError");
-        break;
-    case JSC::ErrorType::URIError:
-        out.print("URIError");
-        break;
-    }
-}
-
-} // namespace WTF
index f94b005..ed02277 100644 (file)
@@ -23,6 +23,7 @@
 #pragma once
 
 #include "ErrorInstance.h"
+#include "ErrorType.h"
 #include "InternalFunction.h"
 #include "JSObject.h"
 #include "ThrowScope.h"
@@ -38,16 +39,6 @@ class JSObject;
 class SourceCode;
 class Structure;
 
-enum class ErrorType : uint8_t {
-    Error,
-    EvalError,
-    RangeError,
-    ReferenceError,
-    SyntaxError,
-    TypeError,
-    URIError,
-};
-
 // ExecState wrappers.
 JSObject* createError(ExecState*, const String&, ErrorInstance::SourceAppender);
 JSObject* createEvalError(ExecState*, const String&, ErrorInstance::SourceAppender);
@@ -105,11 +96,3 @@ inline EncodedJSValue throwVMRangeError(ExecState* state, ThrowScope& scope, con
 inline EncodedJSValue throwVMDOMAttributeGetterTypeError(ExecState* state, ThrowScope& scope, const ClassInfo* classInfo, PropertyName propertyName) { return JSValue::encode(throwDOMAttributeGetterTypeError(state, scope, classInfo, propertyName)); }
 
 } // namespace JSC
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&, JSC::ErrorType);
-
-} // namespace WTF
index 0e620c6..713c738 100644 (file)
@@ -53,12 +53,19 @@ ErrorPrototype::ErrorPrototype(VM& vm, Structure* structure)
 {
 }
 
-void ErrorPrototype::finishCreation(VM& vm)
+ErrorPrototype* ErrorPrototype::create(VM& vm, JSGlobalObject*, Structure* structure)
+{
+    ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
+    prototype->finishCreation(vm, "Error"_s);
+    return prototype;
+}
+
+void ErrorPrototype::finishCreation(VM& vm, const String& name)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
-    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String("Error"_s)), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirect(vm, vm.propertyNames->message, jsEmptyString(&vm), static_cast<unsigned>(PropertyAttribute::DontEnum));
+    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));
 }
 
 // ------------------------------ Functions ---------------------------
index 2f0b4b6..647a24b 100644 (file)
@@ -31,12 +31,7 @@ public:
     typedef JSNonFinalObject Base;
     static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
 
-    static ErrorPrototype* create(VM& vm, JSGlobalObject*, Structure* structure)
-    {
-        ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
-        prototype->finishCreation(vm);
-        return prototype;
-    }
+    static ErrorPrototype* create(VM&, JSGlobalObject*, Structure*);
 
     DECLARE_INFO;
 
@@ -47,7 +42,7 @@ public:
 
 protected:
     ErrorPrototype(VM&, Structure*);
-    void finishCreation(VM&);
+    void finishCreation(VM&, const String&);
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ErrorType.cpp b/Source/JavaScriptCore/runtime/ErrorType.cpp
new file mode 100644 (file)
index 0000000..9e6f13f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ErrorType.h"
+
+namespace JSC {
+
+ASCIILiteral errorTypeName(ErrorType errorType)
+{
+    static const ASCIILiteral errorTypeNames[] = {
+        "Error"_s,
+        "EvalError"_s,
+        "RangeError"_s,
+        "ReferenceError"_s,
+        "SyntaxError"_s,
+        "TypeError"_s,
+        "URIError"_s,
+    };
+    return errorTypeNames[static_cast<unsigned>(errorType)];
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::ErrorType errorType)
+{
+    out.print(JSC::errorTypeName(errorType));
+}
+
+} // namespace WTF
diff --git a/Source/JavaScriptCore/runtime/ErrorType.h b/Source/JavaScriptCore/runtime/ErrorType.h
new file mode 100644 (file)
index 0000000..52b49af
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/text/ASCIILiteral.h>
+
+namespace JSC {
+
+enum class ErrorType : uint8_t {
+    Error = 0,
+    EvalError,
+    RangeError,
+    ReferenceError,
+    SyntaxError,
+    TypeError,
+    URIError,
+};
+static constexpr unsigned NumberOfErrorType { static_cast<unsigned>(ErrorType::URIError) + 1 };
+ASCIILiteral errorTypeName(ErrorType);
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&, JSC::ErrorType);
+
+} // namespace WTF
index 0a0fbf1..c5b0b30 100644 (file)
@@ -303,11 +303,13 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = {
   decodeURIComponent    globalFuncDecodeURIComponent                 DontEnum|Function 1
   encodeURI             globalFuncEncodeURI                          DontEnum|Function 1
   encodeURIComponent    globalFuncEncodeURIComponent                 DontEnum|Function 1
-  EvalError             JSGlobalObject::m_evalErrorConstructor       DontEnum|CellProperty
   globalThis            JSGlobalObject::m_globalThis                 DontEnum|CellProperty
-  ReferenceError        JSGlobalObject::m_referenceErrorConstructor  DontEnum|CellProperty
-  SyntaxError           JSGlobalObject::m_syntaxErrorConstructor     DontEnum|CellProperty
-  URIError              JSGlobalObject::m_URIErrorConstructor        DontEnum|CellProperty
+  EvalError             JSGlobalObject::m_evalErrorStructure         DontEnum|ClassStructure
+  RangeError            JSGlobalObject::m_rangeErrorStructure        DontEnum|ClassStructure
+  ReferenceError        JSGlobalObject::m_referenceErrorStructure    DontEnum|ClassStructure
+  SyntaxError           JSGlobalObject::m_syntaxErrorStructure       DontEnum|ClassStructure
+  TypeError             JSGlobalObject::m_typeErrorStructure         DontEnum|ClassStructure
+  URIError              JSGlobalObject::m_URIErrorStructure          DontEnum|ClassStructure
   Proxy                 createProxyProperty                          DontEnum|PropertyCallback
   JSON                  createJSONProperty                           DontEnum|PropertyCallback
   Math                  createMathProperty                           DontEnum|PropertyCallback
@@ -393,6 +395,14 @@ static JSObject* getGetterById(ExecState* exec, JSObject* base, const Identifier
     return slot.getPureResult().toObject(exec);
 }
 
+template<ErrorType errorType>
+void JSGlobalObject::initializeErrorConstructor(LazyClassStructure::Initializer& init)
+{
+    init.setPrototype(NativeErrorPrototype::create(init.vm, NativeErrorPrototype::createStructure(init.vm, this, m_errorPrototype.get()), errorTypeName(errorType)));
+    init.setStructure(ErrorInstance::createStructure(init.vm, this, init.prototype));
+    init.setConstructor(NativeErrorConstructor<errorType>::create(init.vm, NativeErrorConstructor<errorType>::createStructure(init.vm, this, m_errorConstructor.get()), jsCast<NativeErrorPrototype*>(init.prototype)));
+}
+
 void JSGlobalObject::init(VM& vm)
 {
     ASSERT(vm.currentThreadIsHoldingAPILock());
@@ -704,25 +714,30 @@ m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->c
     m_promiseConstructor.set(vm, this, promiseConstructor);
     m_internalPromiseConstructor.set(vm, this, internalPromiseConstructor);
     
-    m_nativeErrorPrototypeStructure.set(vm, this, NativeErrorPrototype::createStructure(vm, this, m_errorPrototype.get()));
-    m_nativeErrorStructure.set(vm, this, NativeErrorConstructor::createStructure(vm, this, errorConstructor));
-    m_evalErrorConstructor.initLater(
-        [] (const Initializer<NativeErrorConstructor>& init) {
-            init.set(NativeErrorConstructor::create(init.vm, init.owner, init.owner->m_nativeErrorStructure.get(), init.owner->m_nativeErrorPrototypeStructure.get(), "EvalError"_s));
+    m_errorConstructor.set(vm, this, errorConstructor);
+    m_evalErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::EvalError>(init);
         });
-    m_rangeErrorConstructor.set(vm, this, NativeErrorConstructor::create(vm, this, m_nativeErrorStructure.get(), m_nativeErrorPrototypeStructure.get(), "RangeError"_s));
-    m_referenceErrorConstructor.initLater(
-        [] (const Initializer<NativeErrorConstructor>& init) {
-            init.set(NativeErrorConstructor::create(init.vm, init.owner, init.owner->m_nativeErrorStructure.get(), init.owner->m_nativeErrorPrototypeStructure.get(), "ReferenceError"_s));
+    m_rangeErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::RangeError>(init);
         });
-    m_syntaxErrorConstructor.initLater(
-        [] (const Initializer<NativeErrorConstructor>& init) {
-            init.set(NativeErrorConstructor::create(init.vm, init.owner, init.owner->m_nativeErrorStructure.get(), init.owner->m_nativeErrorPrototypeStructure.get(), "SyntaxError"_s));
+    m_referenceErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::ReferenceError>(init);
         });
-    m_typeErrorConstructor.set(vm, this, NativeErrorConstructor::create(vm, this, m_nativeErrorStructure.get(), m_nativeErrorPrototypeStructure.get(), "TypeError"_s));
-    m_URIErrorConstructor.initLater(
-        [] (const Initializer<NativeErrorConstructor>& init) {
-            init.set(NativeErrorConstructor::create(init.vm, init.owner, init.owner->m_nativeErrorStructure.get(), init.owner->m_nativeErrorPrototypeStructure.get(), "URIError"_s));
+    m_syntaxErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::SyntaxError>(init);
+        });
+    m_typeErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::TypeError>(init);
+        });
+    m_URIErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeErrorConstructor<ErrorType::URIError>(init);
         });
 
     m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
@@ -756,8 +771,6 @@ m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->c
     putDirectWithoutTransition(vm, vm.propertyNames->Function, functionConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirectWithoutTransition(vm, vm.propertyNames->Array, arrayConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirectWithoutTransition(vm, vm.propertyNames->RegExp, m_regExpConstructor.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirectWithoutTransition(vm, vm.propertyNames->RangeError, m_rangeErrorConstructor.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirectWithoutTransition(vm, vm.propertyNames->TypeError, m_typeErrorConstructor.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
 
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ObjectPrivateName(), objectConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ArrayPrivateName(), arrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
@@ -878,9 +891,9 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
         GlobalPropertyInfo(vm.propertyNames->builtinNames().propertyIsEnumerablePrivateName(), privateFuncPropertyIsEnumerable, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().importModulePrivateName(), privateFuncImportModule, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().enqueueJobPrivateName(), JSFunction::create(vm, this, 0, String(), enqueueJob), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->builtinNames().ErrorPrivateName(), errorConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->builtinNames().RangeErrorPrivateName(), m_rangeErrorConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->builtinNames().TypeErrorPrivateName(), m_typeErrorConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+        // FIXME: Offer @makeTypeError function instead of exposing @TypeError here.
+        // https://bugs.webkit.org/show_bug.cgi?id=193858
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().TypeErrorPrivateName(), m_typeErrorStructure.constructor(this), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArrayLengthPrivateName(), privateFuncTypedArrayLength, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArrayGetOriginalConstructorPrivateName(), privateFuncTypedArrayGetOriginalConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArraySortPrivateName(), privateFuncTypedArraySort, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
@@ -1548,14 +1561,13 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(thisObject->m_globalCallee);
     visitor.append(thisObject->m_stackOverflowFrameCallee);
     visitor.append(thisObject->m_regExpConstructor);
-    visitor.append(thisObject->m_nativeErrorPrototypeStructure);
-    visitor.append(thisObject->m_nativeErrorStructure);
-    thisObject->m_evalErrorConstructor.visit(visitor);
-    visitor.append(thisObject->m_rangeErrorConstructor);
-    thisObject->m_referenceErrorConstructor.visit(visitor);
-    thisObject->m_syntaxErrorConstructor.visit(visitor);
-    visitor.append(thisObject->m_typeErrorConstructor);
-    thisObject->m_URIErrorConstructor.visit(visitor);
+    visitor.append(thisObject->m_errorConstructor);
+    thisObject->m_evalErrorStructure.visit(visitor);
+    thisObject->m_rangeErrorStructure.visit(visitor);
+    thisObject->m_referenceErrorStructure.visit(visitor);
+    thisObject->m_syntaxErrorStructure.visit(visitor);
+    thisObject->m_typeErrorStructure.visit(visitor);
+    thisObject->m_URIErrorStructure.visit(visitor);
     visitor.append(thisObject->m_objectConstructor);
     visitor.append(thisObject->m_promiseConstructor);
 
index 4462ab1..c05e02b 100644 (file)
@@ -25,6 +25,7 @@
 #include "ArrayBufferSharingMode.h"
 #include "BigIntPrototype.h"
 #include "BooleanPrototype.h"
+#include "ErrorType.h"
 #include "ExceptionHelpers.h"
 #include "InternalFunction.h"
 #include "JSArray.h"
@@ -101,7 +102,7 @@ class MapPrototype;
 class Microtask;
 class ModuleLoader;
 class ModuleProgramExecutable;
-class NativeErrorConstructor;
+class NativeErrorConstructorBase;
 class NullGetterFunction;
 class NullSetterFunction;
 class ObjectConstructor;
@@ -259,14 +260,15 @@ public:
     WriteBarrier<JSCallee> m_globalCallee;
     WriteBarrier<JSCallee> m_stackOverflowFrameCallee;
     WriteBarrier<RegExpConstructor> m_regExpConstructor;
-    WriteBarrier<Structure> m_nativeErrorPrototypeStructure;
-    WriteBarrier<Structure> m_nativeErrorStructure;
-    LazyProperty<JSGlobalObject, NativeErrorConstructor> m_evalErrorConstructor;
-    WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
-    LazyProperty<JSGlobalObject, NativeErrorConstructor> m_referenceErrorConstructor;
-    LazyProperty<JSGlobalObject, NativeErrorConstructor> m_syntaxErrorConstructor;
-    WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
-    LazyProperty<JSGlobalObject, NativeErrorConstructor> m_URIErrorConstructor;
+
+    WriteBarrier<ErrorConstructor> m_errorConstructor;
+    LazyClassStructure m_evalErrorStructure;
+    LazyClassStructure m_rangeErrorStructure;
+    LazyClassStructure m_referenceErrorStructure;
+    LazyClassStructure m_syntaxErrorStructure;
+    LazyClassStructure m_typeErrorStructure;
+    LazyClassStructure m_URIErrorStructure;
+
     WriteBarrier<ObjectConstructor> m_objectConstructor;
     WriteBarrier<ArrayConstructor> m_arrayConstructor;
     WriteBarrier<JSPromiseConstructor> m_promiseConstructor;
@@ -580,12 +582,6 @@ public:
     ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); }
     JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); }
     JSInternalPromiseConstructor* internalPromiseConstructor() const { return m_internalPromiseConstructor.get(); }
-    NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(this); }
-    NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
-    NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(this); }
-    NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(this); }
-    NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
-    NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(this); }
 
 #if ENABLE(INTL)
     IntlObject* intlObject() const { return m_intlObject.get(); }
@@ -693,6 +689,27 @@ public:
     Structure* dateStructure() const { return m_dateStructure.get(this); }
     Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
     Structure* errorStructure() const { return m_errorStructure.get(); }
+    Structure* errorStructure(ErrorType errorType) const
+    {
+        switch (errorType) {
+        case ErrorType::Error:
+            return errorStructure();
+        case ErrorType::EvalError:
+            return m_evalErrorStructure.get(this);
+        case ErrorType::RangeError:
+            return m_rangeErrorStructure.get(this);
+        case ErrorType::ReferenceError:
+            return m_referenceErrorStructure.get(this);
+        case ErrorType::SyntaxError:
+            return m_syntaxErrorStructure.get(this);
+        case ErrorType::TypeError:
+            return m_typeErrorStructure.get(this);
+        case ErrorType::URIError:
+            return m_URIErrorStructure.get(this);
+        }
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
     Structure* calleeStructure() const { return m_calleeStructure.get(); }
     Structure* hostFunctionStructure() const { return m_hostFunctionStructure.get(); }
 
@@ -1000,6 +1017,9 @@ private:
     void fireWatchpointAndMakeAllArrayStructuresSlowPut(VM&);
     void setGlobalThis(VM&, JSObject* globalThis);
 
+    template<ErrorType errorType>
+    void initializeErrorConstructor(LazyClassStructure::Initializer&);
+
     JS_EXPORT_PRIVATE void init(VM&);
 
     JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
index 8f3dd70..5356562 100644 (file)
 
 namespace JSC {
 
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NativeErrorConstructor);
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NativeErrorConstructorBase);
 
-const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NativeErrorConstructor) };
+const ClassInfo NativeErrorConstructorBase::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NativeErrorConstructorBase) };
 
-NativeErrorConstructor::NativeErrorConstructor(VM& vm, Structure* structure)
-    : InternalFunction(vm, structure, Interpreter::callNativeErrorConstructor, Interpreter::constructWithNativeErrorConstructor)
+template<ErrorType errorType>
+NativeErrorConstructor<errorType>::NativeErrorConstructor(VM& vm, Structure* structure)
+    : NativeErrorConstructorBase(vm, structure, NativeErrorConstructor<errorType>::callNativeErrorConstructor, NativeErrorConstructor<errorType>::constructNativeErrorConstructor)
 {
 }
 
-void NativeErrorConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, Structure* prototypeStructure, const String& name)
+void NativeErrorConstructorBase::finishCreation(VM& vm, NativeErrorPrototype* prototype, ErrorType errorType)
 {
-    Base::finishCreation(vm, name);
+    Base::finishCreation(vm, errorTypeName(errorType));
     ASSERT(inherits(vm, info()));
     
-    NativeErrorPrototype* prototype = NativeErrorPrototype::create(vm, prototypeStructure, name, this);
-    
-    putDirect(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
-    putDirect(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
-    m_errorStructure.set(vm, this, ErrorInstance::createStructure(vm, globalObject, prototype));
-    ASSERT(m_errorStructure);
-    ASSERT(m_errorStructure->isObject());
-}
-
-void NativeErrorConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    NativeErrorConstructor* thisObject = jsCast<NativeErrorConstructor*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(thisObject->m_errorStructure);
+    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
 }
 
-EncodedJSValue JSC_HOST_CALL Interpreter::constructWithNativeErrorConstructor(ExecState* exec)
+template<ErrorType errorType>
+EncodedJSValue JSC_HOST_CALL NativeErrorConstructor<errorType>::constructNativeErrorConstructor(ExecState* exec)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue message = exec->argument(0);
-    Structure* errorStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), jsCast<NativeErrorConstructor*>(exec->jsCallee())->errorStructure());
+    Structure* errorStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), jsCast<NativeErrorConstructor*>(exec->jsCallee())->errorStructure(vm));
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     ASSERT(errorStructure);
     RELEASE_AND_RETURN(scope, JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false)));
 }
 
-EncodedJSValue JSC_HOST_CALL Interpreter::callNativeErrorConstructor(ExecState* exec)
+template<ErrorType errorType>
+EncodedJSValue JSC_HOST_CALL NativeErrorConstructor<errorType>::callNativeErrorConstructor(ExecState* exec)
 {
+    VM& vm = exec->vm();
     JSValue message = exec->argument(0);
-    Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->jsCallee())->errorStructure();
+    Structure* errorStructure = jsCast<NativeErrorConstructor*>(exec->jsCallee())->errorStructure(vm);
     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
 }
 
+template class NativeErrorConstructor<ErrorType::EvalError>;
+template class NativeErrorConstructor<ErrorType::RangeError>;
+template class NativeErrorConstructor<ErrorType::ReferenceError>;
+template class NativeErrorConstructor<ErrorType::SyntaxError>;
+template class NativeErrorConstructor<ErrorType::TypeError>;
+template class NativeErrorConstructor<ErrorType::URIError>;
+
 } // namespace JSC
index 827a096..7307d01 100644 (file)
@@ -20,6 +20,7 @@
 
 #pragma once
 
+#include "Error.h"
 #include "InternalFunction.h"
 #include "NativeErrorPrototype.h"
 
@@ -29,40 +30,56 @@ class ErrorInstance;
 class FunctionPrototype;
 class NativeErrorPrototype;
 
-class NativeErrorConstructor final : public InternalFunction {
+class NativeErrorConstructorBase : public InternalFunction {
 public:
-    typedef InternalFunction Base;
+    using Base = InternalFunction;
 
-    template<typename CellType>
-    static IsoSubspace* subspaceFor(VM& vm)
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return &vm.nativeErrorConstructorSpace;
+        return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
     }
 
-    static NativeErrorConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name)
+protected:
+    NativeErrorConstructorBase(VM& vm, Structure* structure, NativeFunction functionForCall, NativeFunction functionForConstruct)
+        : InternalFunction(vm, structure, functionForCall, functionForConstruct)
     {
-        NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
-        constructor->finishCreation(vm, globalObject, prototypeStructure, name);
-        return constructor;
     }
 
-    DECLARE_INFO;
+    void finishCreation(VM&, NativeErrorPrototype*, ErrorType);
+};
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+template<ErrorType errorType>
+class NativeErrorConstructor final : public NativeErrorConstructorBase {
+public:
+    static NativeErrorConstructor* create(VM& vm, Structure* structure, NativeErrorPrototype* prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+        NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
+        constructor->finishCreation(vm, prototype, errorType);
+        return constructor;
     }
 
-    Structure* errorStructure() { return m_errorStructure.get(); }
-
-protected:
-    void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
-
+    Structure* errorStructure(VM& vm) { return globalObject(vm)->errorStructure(errorType); }
 private:
-    NativeErrorConstructor(VM&, Structure*);
-    static void visitChildren(JSCell*, SlotVisitor&);
+    static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
+    static EncodedJSValue JSC_HOST_CALL constructNativeErrorConstructor(ExecState*);
 
-    WriteBarrier<Structure> m_errorStructure;
+    NativeErrorConstructor(VM&, Structure*);
 };
 
+using EvalErrorConstructor = NativeErrorConstructor<ErrorType::EvalError>;
+using RangeErrorConstructor = NativeErrorConstructor<ErrorType::RangeError>;
+using ReferenceErrorConstructor = NativeErrorConstructor<ErrorType::ReferenceError>;
+using SyntaxErrorConstructor = NativeErrorConstructor<ErrorType::SyntaxError>;
+using TypeErrorConstructor = NativeErrorConstructor<ErrorType::TypeError>;
+using URIErrorConstructor = NativeErrorConstructor<ErrorType::URIError>;
+
+static_assert(sizeof(EvalErrorConstructor) == sizeof(InternalFunction), "");
+static_assert(sizeof(RangeErrorConstructor) == sizeof(InternalFunction), "");
+static_assert(sizeof(ReferenceErrorConstructor) == sizeof(InternalFunction), "");
+static_assert(sizeof(SyntaxErrorConstructor) == sizeof(InternalFunction), "");
+static_assert(sizeof(TypeErrorConstructor) == sizeof(InternalFunction), "");
+static_assert(sizeof(URIErrorConstructor) == sizeof(InternalFunction), "");
+
 } // namespace JSC
index 2486793..5b52071 100644 (file)
@@ -33,12 +33,4 @@ NativeErrorPrototype::NativeErrorPrototype(VM& vm, Structure* structure)
 {
 }
 
-void NativeErrorPrototype::finishCreation(VM& vm, const WTF::String& nameAndMessage, NativeErrorConstructor* constructor)
-{
-    Base::finishCreation(vm);
-    putDirect(vm, vm.propertyNames->name, jsString(&vm, nameAndMessage), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirect(vm, vm.propertyNames->message, jsEmptyString(&vm), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirect(vm, vm.propertyNames->constructor, constructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
-}
-
 } // namespace JSC
index e6c2b5a..a58c1b1 100644 (file)
@@ -24,8 +24,6 @@
 
 namespace JSC {
 
-class NativeErrorConstructor;
-
 class NativeErrorPrototype final : public ErrorPrototype {
 private:
     NativeErrorPrototype(VM&, Structure*);
@@ -33,15 +31,12 @@ private:
 public:
     typedef ErrorPrototype Base;
 
-    static NativeErrorPrototype* create(VM& vm, Structure* structure, const String& name, NativeErrorConstructor* constructor)
+    static NativeErrorPrototype* create(VM& vm, Structure* structure, const String& name)
     {
         NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(vm.heap)) NativeErrorPrototype(vm, structure);
-        prototype->finishCreation(vm, name, constructor);
+        prototype->finishCreation(vm, name);
         return prototype;
     }
-
-protected:
-    void finishCreation(VM&, const String& nameAndMessage, NativeErrorConstructor*);
 };
 
 } // namespace JSC
index cb2dc47..15c66a7 100644 (file)
@@ -302,7 +302,6 @@ VM::VM(VMType vmType, HeapType heapType)
     , generatorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSGeneratorFunction)
     , inferredValueSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredValue)
     , internalFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), InternalFunction)
-    , nativeErrorConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), NativeErrorConstructor)
     , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable)
     , nativeStdFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSNativeStdFunction)
 #if JSC_OBJC_API_ENABLED
index 3f4accf..925b8a6 100644 (file)
@@ -377,7 +377,6 @@ public:
     IsoSubspace generatorFunctionSpace;
     IsoSubspace inferredValueSpace;
     IsoSubspace internalFunctionSpace;
-    IsoSubspace nativeErrorConstructorSpace;
     IsoSubspace nativeExecutableSpace;
     IsoSubspace nativeStdFunctionSpace;
 #if JSC_OBJC_API_ENABLED
index ee00fc8..7b32c7c 100644 (file)
@@ -104,7 +104,7 @@ static Expected<MacroAssemblerCodeRef<WasmEntryPtrTag>, BindingFailure> handleBa
             {
                 auto throwScope = DECLARE_THROW_SCOPE(*vm);
                 JSGlobalObject* globalObject = instance->globalObject(*vm);
-                auto* error = ErrorInstance::create(exec, *vm, globalObject->typeErrorConstructor()->errorStructure(), "i64 not allowed as return type or argument to an imported function"_s);
+                auto* error = ErrorInstance::create(exec, *vm, globalObject->errorStructure(ErrorType::TypeError), "i64 not allowed as return type or argument to an imported function"_s);
                 throwException(exec, throwScope, error);
             }