Exception is a JSCell, not a JSObject.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Mar 2019 10:16:58 +0000 (10:16 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Mar 2019 10:16:58 +0000 (10:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195392

Reviewed by Saam Barati.

Source/JavaScriptCore:

Exception is a VM implementation construct to carry a stack trace for the point
where it is thrown from.  As a reminder, an Exception is needed because:
1. JS code can throw primitives as well that are non-cells.
2. Error objects capture the stack trace at the point where they are constructed,
   which is not always the same as the point where they are thrown (if they are
   thrown).

Hence, Exception should not be visible to JS code, and therefore should not be a
JSObject.  Hence, it should not inherit from JSDestructibleObject.

This patch changes the following:

1. Exception now inherits directly from JSCell instead.

2. Places where we return an Exception masquerading as a JSObject* are now
   updated to return a nullptr when we encounter an exception.

3. We still return Exception* as JSValue or EncodedJSValue when we encounter an
   exception in functions that return JSValue or EncodedJSValue.  This is because
   the number that implements the following pattern is too numerous:

        return throw<Some Error>(...)

   We'll leave these as is for now.

* bytecode/CodeBlock.h:
(JSC::ScriptExecutable::prepareForExecution):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeModuleProgram):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/ConstructData.cpp:
(JSC::construct):
* runtime/Error.cpp:
(JSC::throwConstructorCannotBeCalledAsFunctionTypeError):
(JSC::throwTypeError):
(JSC::throwSyntaxError):
* runtime/Error.h:
(JSC::throwRangeError):
* runtime/Exception.cpp:
(JSC::Exception::createStructure):
* runtime/Exception.h:
* runtime/ExceptionHelpers.cpp:
(JSC::throwOutOfMemoryError):
(JSC::throwStackOverflowError):
(JSC::throwTerminatedExecutionException):
* runtime/ExceptionHelpers.h:
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::resolvedOptions):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
* runtime/JSObject.h:
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorSeal):
(JSC::objectConstructorFreeze):
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::initializeGlobalProperties):
* runtime/RegExpConstructor.cpp:
(JSC::regExpCreate):
(JSC::constructRegExp):
* runtime/ScriptExecutable.cpp:
(JSC::ScriptExecutable::newCodeBlockFor):
(JSC::ScriptExecutable::prepareForExecutionImpl):
* runtime/ScriptExecutable.h:
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::throwException):
* runtime/ThrowScope.h:
(JSC::ThrowScope::throwException):
(JSC::throwException):
* runtime/VM.cpp:
(JSC::VM::throwException):
* runtime/VM.h:

Source/WebCore:

* bridge/objc/objc_utility.h:
* bridge/objc/objc_utility.mm:
(JSC::Bindings::throwError):
* bridge/runtime_object.cpp:
(JSC::Bindings::RuntimeObject::throwInvalidAccessError):
* bridge/runtime_object.h:

Source/WebKit:

* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::JSNPObject::throwInvalidAccessError):
* WebProcess/Plugins/Netscape/JSNPObject.h:

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

33 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/ConstructData.cpp
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/Error.h
Source/JavaScriptCore/runtime/Exception.cpp
Source/JavaScriptCore/runtime/Exception.h
Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Source/JavaScriptCore/runtime/ExceptionHelpers.h
Source/JavaScriptCore/runtime/FunctionConstructor.cpp
Source/JavaScriptCore/runtime/IntlPluralRules.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ProgramExecutable.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/ScriptExecutable.cpp
Source/JavaScriptCore/runtime/ScriptExecutable.h
Source/JavaScriptCore/runtime/ThrowScope.cpp
Source/JavaScriptCore/runtime/ThrowScope.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/WebCore/ChangeLog
Source/WebCore/bridge/objc/objc_utility.h
Source/WebCore/bridge/objc/objc_utility.mm
Source/WebCore/bridge/runtime_object.cpp
Source/WebCore/bridge/runtime_object.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.cpp
Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h

index b001b6f..7ac7a76 100644 (file)
@@ -1,3 +1,92 @@
+2019-03-06  Mark Lam  <mark.lam@apple.com>
+
+        Exception is a JSCell, not a JSObject.
+        https://bugs.webkit.org/show_bug.cgi?id=195392
+
+        Reviewed by Saam Barati.
+
+        Exception is a VM implementation construct to carry a stack trace for the point
+        where it is thrown from.  As a reminder, an Exception is needed because:
+        1. JS code can throw primitives as well that are non-cells.
+        2. Error objects capture the stack trace at the point where they are constructed,
+           which is not always the same as the point where they are thrown (if they are
+           thrown).
+
+        Hence, Exception should not be visible to JS code, and therefore should not be a
+        JSObject.  Hence, it should not inherit from JSDestructibleObject.
+
+        This patch changes the following:
+
+        1. Exception now inherits directly from JSCell instead.
+
+        2. Places where we return an Exception masquerading as a JSObject* are now
+           updated to return a nullptr when we encounter an exception.
+
+        3. We still return Exception* as JSValue or EncodedJSValue when we encounter an
+           exception in functions that return JSValue or EncodedJSValue.  This is because
+           the number that implements the following pattern is too numerous:
+
+                return throw<Some Error>(...)
+
+           We'll leave these as is for now.
+
+        * bytecode/CodeBlock.h:
+        (JSC::ScriptExecutable::prepareForExecution):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeProgram):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeModuleProgram):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/ConstructData.cpp:
+        (JSC::construct):
+        * runtime/Error.cpp:
+        (JSC::throwConstructorCannotBeCalledAsFunctionTypeError):
+        (JSC::throwTypeError):
+        (JSC::throwSyntaxError):
+        * runtime/Error.h:
+        (JSC::throwRangeError):
+        * runtime/Exception.cpp:
+        (JSC::Exception::createStructure):
+        * runtime/Exception.h:
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::throwOutOfMemoryError):
+        (JSC::throwStackOverflowError):
+        (JSC::throwTerminatedExecutionException):
+        * runtime/ExceptionHelpers.h:
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunction):
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+        * runtime/IntlPluralRules.cpp:
+        (JSC::IntlPluralRules::resolvedOptions):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewWithArguments):
+        * runtime/JSObject.h:
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        * runtime/ProgramExecutable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::regExpCreate):
+        (JSC::constructRegExp):
+        * runtime/ScriptExecutable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        (JSC::ScriptExecutable::prepareForExecutionImpl):
+        * runtime/ScriptExecutable.h:
+        * runtime/ThrowScope.cpp:
+        (JSC::ThrowScope::throwException):
+        * runtime/ThrowScope.h:
+        (JSC::ThrowScope::throwException):
+        (JSC::throwException):
+        * runtime/VM.cpp:
+        (JSC::VM::throwException):
+        * runtime/VM.h:
+
 2019-03-06  Ross Kirsling  <ross.kirsling@sony.com>
 
         [Win] Remove -DUCHAR_TYPE=wchar_t stopgap and learn to live with char16_t.
index db2cd92..cbc7ac2 100644 (file)
@@ -1034,7 +1034,7 @@ inline Register& ExecState::uncheckedR(VirtualRegister reg)
 }
 
 template <typename ExecutableType>
-JSObject* ScriptExecutable::prepareForExecution(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
+Exception* ScriptExecutable::prepareForExecution(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
 {
     if (hasJITCodeFor(kind)) {
         if (std::is_same<ExecutableType, EvalExecutable>::value)
index 1a662ea..fa93028 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -808,8 +808,8 @@ failedJSONP:
     ProgramCodeBlock* codeBlock;
     {
         CodeBlock* tempCodeBlock;
-        JSObject* error = program->prepareForExecution<ProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(error));
+        Exception* error = program->prepareForExecution<ProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        EXCEPTION_ASSERT(throwScope.exception() == error);
         if (UNLIKELY(error))
             return checkedReturn(error);
         codeBlock = jsCast<ProgramCodeBlock*>(tempCodeBlock);
@@ -866,8 +866,8 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
 
     if (isJSCall) {
         // Compile the callee:
-        JSObject* compileError = callData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(function), scope, CodeForCall, newCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(compileError));
+        Exception* compileError = callData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(function), scope, CodeForCall, newCodeBlock);
+        EXCEPTION_ASSERT(throwScope.exception() == compileError);
         if (UNLIKELY(!!compileError))
             return checkedReturn(compileError);
 
@@ -909,8 +909,10 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
     ASSERT(!vm.isCollectorBusyOnCurrentThread());
     // We throw in this case because we have to return something "valid" but we're
     // already in an invalid state.
-    if (vm.isCollectorBusyOnCurrentThread())
-        return checkedReturn(throwStackOverflowError(callFrame, throwScope));
+    if (UNLIKELY(vm.isCollectorBusyOnCurrentThread())) {
+        throwStackOverflowError(callFrame, throwScope);
+        return nullptr;
+    }
 
     bool isJSConstruct = (constructType == ConstructType::JS);
     JSScope* scope = nullptr;
@@ -928,15 +930,17 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
     }
 
     VMEntryScope entryScope(vm, globalObject);
-    if (UNLIKELY(!vm.isSafeToRecurseSoft()))
-        return checkedReturn(throwStackOverflowError(callFrame, throwScope));
+    if (UNLIKELY(!vm.isSafeToRecurseSoft())) {
+        throwStackOverflowError(callFrame, throwScope);
+        return nullptr;
+    }
 
     if (isJSConstruct) {
         // Compile the callee:
-        JSObject* compileError = constructData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(constructor), scope, CodeForConstruct, newCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(compileError));
+        Exception* compileError = constructData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(constructor), scope, CodeForConstruct, newCodeBlock);
+        EXCEPTION_ASSERT(throwScope.exception() == compileError);
         if (UNLIKELY(!!compileError))
-            return checkedReturn(compileError);
+            return nullptr;
 
         ASSERT(!!newCodeBlock);
         newCodeBlock->m_shouldAlwaysBeInlined = false;
@@ -946,7 +950,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
     VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     if (UNLIKELY(vm.needTrapHandling(mask))) {
         vm.handleTraps(callFrame, mask);
-        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+        RETURN_IF_EXCEPTION(throwScope, nullptr);
     }
 
     ProtoCallFrame protoCallFrame;
@@ -981,8 +985,8 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
 
     // Compile the callee:
     CodeBlock* newCodeBlock;
-    JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, function, scope, CodeForCall, newCodeBlock);
-    EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(error));
+    Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, function, scope, CodeForCall, newCodeBlock);
+    EXCEPTION_ASSERT(throwScope.exception() == error);
     if (UNLIKELY(error))
         return CallFrameClosure();
     newCodeBlock->m_shouldAlwaysBeInlined = false;
@@ -1039,8 +1043,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     EvalCodeBlock* codeBlock;
     {
         CodeBlock* tempCodeBlock;
-        JSObject* compileError = eval->prepareForExecution<EvalExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(compileError));
+        Exception* compileError = eval->prepareForExecution<EvalExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        EXCEPTION_ASSERT(throwScope.exception() == compileError);
         if (UNLIKELY(!!compileError))
             return checkedReturn(compileError);
         codeBlock = jsCast<EvalCodeBlock*>(tempCodeBlock);
@@ -1163,8 +1167,8 @@ JSValue Interpreter::executeModuleProgram(ModuleProgramExecutable* executable, C
     ModuleProgramCodeBlock* codeBlock;
     {
         CodeBlock* tempCodeBlock;
-        JSObject* compileError = executable->prepareForExecution<ModuleProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(compileError));
+        Exception* compileError = executable->prepareForExecution<ModuleProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        EXCEPTION_ASSERT(throwScope.exception() == compileError);
         if (UNLIKELY(!!compileError))
             return checkedReturn(compileError);
         codeBlock = jsCast<ModuleProgramCodeBlock*>(tempCodeBlock);
index f24ff18..a496ce5 100644 (file)
@@ -1042,9 +1042,9 @@ SlowPathReturnType JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLi
         }
 
         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
-        JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, *codeBlockSlot);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(error));
-        if (error)
+        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, *codeBlockSlot);
+        EXCEPTION_ASSERT(throwScope.exception() == error);
+        if (UNLIKELY(error))
             return handleThrowException();
         codeBlock = *codeBlockSlot;
         ArityCheckMode arity;
@@ -1098,9 +1098,9 @@ void JIT_OPERATION operationLinkDirectCall(ExecState* exec, CallLinkInfo* callLi
 
         RELEASE_ASSERT(isCall(kind) || functionExecutable->constructAbility() != ConstructAbility::CannotConstruct);
         
-        JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, codeBlock);
-        EXCEPTION_ASSERT_UNUSED(throwScope, throwScope.exception() == reinterpret_cast<Exception*>(error));
-        if (error)
+        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, callee, scope, kind, codeBlock);
+        EXCEPTION_ASSERT_UNUSED(throwScope, throwScope.exception() == error);
+        if (UNLIKELY(error))
             return;
         unsigned argumentStackSlots = callLinkInfo->maxNumArguments();
         if (argumentStackSlots < static_cast<size_t>(codeBlock->numParameters()))
@@ -1147,9 +1147,9 @@ inline SlowPathReturnType virtualForWithFunction(
         }
 
         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
-        JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, function, scope, kind, *codeBlockSlot);
-        EXCEPTION_ASSERT(throwScope.exception() == reinterpret_cast<Exception*>(error));
-        if (error) {
+        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(*vm, function, scope, kind, *codeBlockSlot);
+        EXCEPTION_ASSERT(throwScope.exception() == error);
+        if (UNLIKELY(error)) {
             return encodeResult(
                 vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
                 reinterpret_cast<void*>(KeepTheFrame));
index 8b54362..7fc3730 100644 (file)
@@ -1527,7 +1527,7 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, CodeSpecializationKin
             LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
 
         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
-        JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
+        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
         EXCEPTION_ASSERT(throwScope.exception() == error);
         if (UNLIKELY(error))
             LLINT_CALL_THROW(exec, error);
index 878b089..d99bb48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2016 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-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
@@ -41,8 +41,10 @@ JSObject* construct(ExecState* exec, JSValue constructorObject, const ArgList& a
 
     ConstructData constructData;
     ConstructType constructType = getConstructData(vm, constructorObject, constructData);
-    if (constructType == ConstructType::None)
-        return throwTypeError(exec, scope, errorMessage);
+    if (UNLIKELY(constructType == ConstructType::None)) {
+        throwTypeError(exec, scope, errorMessage);
+        return nullptr;
+    }
 
     RELEASE_AND_RETURN(scope, construct(exec, constructorObject, constructType, constructData, args, constructorObject));
 }
index 9d78664..09ba627 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
  *
  *  This library is free software; you can redistribute it and/or
@@ -260,32 +260,32 @@ JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const So
     return error;
 }
 
-JSObject* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState* exec, ThrowScope& scope, const char* constructorName)
+Exception* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState* exec, ThrowScope& scope, const char* constructorName)
 {
     return throwTypeError(exec, scope, makeString("calling ", constructorName, " constructor without new is invalid"));
 }
 
-JSObject* throwTypeError(ExecState* exec, ThrowScope& scope)
+Exception* throwTypeError(ExecState* exec, ThrowScope& scope)
 {
     return throwException(exec, scope, createTypeError(exec));
 }
 
-JSObject* throwTypeError(ExecState* exec, ThrowScope& scope, ASCIILiteral errorMessage)
+Exception* throwTypeError(ExecState* exec, ThrowScope& scope, ASCIILiteral errorMessage)
 {
     return throwTypeError(exec, scope, String(errorMessage));
 }
 
-JSObject* throwTypeError(ExecState* exec, ThrowScope& scope, const String& message)
+Exception* throwTypeError(ExecState* exec, ThrowScope& scope, const String& message)
 {
     return throwException(exec, scope, createTypeError(exec, message));
 }
 
-JSObject* throwSyntaxError(ExecState* exec, ThrowScope& scope)
+Exception* throwSyntaxError(ExecState* exec, ThrowScope& scope)
 {
     return throwException(exec, scope, createSyntaxError(exec, "Syntax error"_s));
 }
 
-JSObject* throwSyntaxError(ExecState* exec, ThrowScope& scope, const String& message)
+Exception* throwSyntaxError(ExecState* exec, ThrowScope& scope, const String& message)
 {
     return throwException(exec, scope, createSyntaxError(exec, message));
 }
index ed02277..f1f9d85 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -24,6 +24,7 @@
 
 #include "ErrorInstance.h"
 #include "ErrorType.h"
+#include "Exception.h"
 #include "InternalFunction.h"
 #include "JSObject.h"
 #include "ThrowScope.h"
@@ -76,13 +77,13 @@ JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&)
 // Methods to throw Errors.
 
 // Convenience wrappers, create an throw an exception with a default message.
-JS_EXPORT_PRIVATE JSObject* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState*, ThrowScope&, const char* constructorName);
-JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, ThrowScope&);
-JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, ThrowScope&, ASCIILiteral errorMessage);
-JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, ThrowScope&, const String& errorMessage);
-JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*, ThrowScope&);
-JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*, ThrowScope&, const String& errorMessage);
-inline JSObject* throwRangeError(ExecState* state, ThrowScope& scope, const String& errorMessage) { return throwException(state, scope, createRangeError(state, errorMessage)); }
+JS_EXPORT_PRIVATE Exception* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState*, ThrowScope&, const char* constructorName);
+JS_EXPORT_PRIVATE Exception* throwTypeError(ExecState*, ThrowScope&);
+JS_EXPORT_PRIVATE Exception* throwTypeError(ExecState*, ThrowScope&, ASCIILiteral errorMessage);
+JS_EXPORT_PRIVATE Exception* throwTypeError(ExecState*, ThrowScope&, const String& errorMessage);
+JS_EXPORT_PRIVATE Exception* throwSyntaxError(ExecState*, ThrowScope&);
+JS_EXPORT_PRIVATE Exception* throwSyntaxError(ExecState*, ThrowScope&, const String& errorMessage);
+inline Exception* throwRangeError(ExecState* state, ThrowScope& scope, const String& errorMessage) { return throwException(state, scope, createRangeError(state, errorMessage)); }
 JS_EXPORT_PRIVATE JSValue throwDOMAttributeGetterTypeError(ExecState*, ThrowScope&, const ClassInfo*, PropertyName);
 
 // Convenience wrappers, wrap result as an EncodedJSValue.
index bc989ef..d943194 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -31,7 +31,7 @@
 
 namespace JSC {
 
-const ClassInfo Exception::s_info = { "Exception", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Exception) };
+const ClassInfo Exception::s_info = { "Exception", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(Exception) };
 
 Exception* Exception::create(VM& vm, JSValue thrownValue, StackCaptureAction action)
 {
@@ -48,7 +48,7 @@ void Exception::destroy(JSCell* cell)
 
 Structure* Exception::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 {
-    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
 }
 
 void Exception::visitChildren(JSCell* cell, SlotVisitor& visitor)
index 8de113e..a8c7180 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
 
 namespace JSC {
     
-class Exception final : public JSDestructibleObject {
+class Exception final : public JSCell {
 public:
-    typedef JSDestructibleObject Base;
+    using Base = JSCell;
     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+    static const bool needsDestruction = true;
 
     enum StackCaptureAction {
         CaptureStack,
index a37446e..4ea4497 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-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
@@ -324,19 +324,19 @@ JSObject* createTDZError(ExecState* exec)
     return createReferenceError(exec, "Cannot access uninitialized variable.");
 }
 
-JSObject* throwOutOfMemoryError(ExecState* exec, ThrowScope& scope)
+Exception* throwOutOfMemoryError(ExecState* exec, ThrowScope& scope)
 {
     return throwException(exec, scope, createOutOfMemoryError(exec));
 }
 
-JSObject* throwStackOverflowError(ExecState* exec, ThrowScope& scope)
+Exception* throwStackOverflowError(ExecState* exec, ThrowScope& scope)
 {
     VM& vm = exec->vm();
     ErrorHandlingScope errorScope(vm);
     return throwException(exec, scope, createStackOverflowError(exec));
 }
 
-JSObject* throwTerminatedExecutionException(ExecState* exec, ThrowScope& scope)
+Exception* throwTerminatedExecutionException(ExecState* exec, ThrowScope& scope)
 {
     VM& vm = exec->vm();
     ErrorHandlingScope errorScope(vm);
index ce57ef1..d135858 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-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
@@ -29,6 +29,7 @@
 #pragma once
 
 #include "ErrorInstance.h"
+#include "Exception.h"
 #include "JSObject.h"
 #include "ThrowScope.h"
 
@@ -55,9 +56,9 @@ JSObject* createNotAFunctionError(ExecState*, JSValue);
 JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const String&);
 JSString* errorDescriptionForValue(ExecState*, JSValue);
 
-JS_EXPORT_PRIVATE JSObject* throwOutOfMemoryError(ExecState*, ThrowScope&);
-JS_EXPORT_PRIVATE JSObject* throwStackOverflowError(ExecState*, ThrowScope&);
-JS_EXPORT_PRIVATE JSObject* throwTerminatedExecutionException(ExecState*, ThrowScope&);
+JS_EXPORT_PRIVATE Exception* throwOutOfMemoryError(ExecState*, ThrowScope&);
+JS_EXPORT_PRIVATE Exception* throwStackOverflowError(ExecState*, ThrowScope&);
+JS_EXPORT_PRIVATE Exception* throwTerminatedExecutionException(ExecState*, ThrowScope&);
 
 
 class TerminatedExecutionError final : public JSNonFinalObject {
index c84c972..b9e42bf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -69,8 +69,10 @@ JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!globalObject->evalEnabled())
-        return throwException(exec, scope, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
+    if (UNLIKELY(!globalObject->evalEnabled())) {
+        throwException(exec, scope, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
+        return nullptr;
+    }
     RELEASE_AND_RETURN(scope, constructFunctionSkippingEvalEnabledCheck(exec, globalObject, args, functionName, sourceOrigin, sourceURL, position, -1, functionConstructionMode, newTarget));
 }
 
@@ -145,9 +147,10 @@ JSObject* constructFunctionSkippingEvalEnabledCheck(
     SourceCode source = makeSource(program, sourceOrigin, URL({ }, sourceURL), position);
     JSObject* exception = nullptr;
     FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, *exec, source, exception, overrideLineNumber, functionConstructorParametersEndPosition);
-    if (!function) {
+    if (UNLIKELY(!function)) {
         ASSERT(exception);
-        return throwException(exec, scope, exception);
+        throwException(exec, scope, exception);
+        return nullptr;
     }
 
     Structure* structure = nullptr;
index 5ff9c0b..bb4d8f2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2018 Andy VanWagoner (andy@vanwagoner.family)
+ * 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
@@ -200,8 +201,10 @@ JSObject* IntlPluralRules::resolvedOptions(ExecState& exec)
 
     // 13.4.4 Intl.PluralRules.prototype.resolvedOptions ()
     // https://tc39.github.io/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
-    if (!m_initializedPluralRules)
-        return throwTypeError(&exec, scope, "Intl.PluralRules.prototype.resolvedOptions called on value that's not an object initialized as a PluralRules"_s);
+    if (UNLIKELY(!m_initializedPluralRules)) {
+        throwTypeError(&exec, scope, "Intl.PluralRules.prototype.resolvedOptions called on value that's not an object initialized as a PluralRules"_s);
+        return nullptr;
+    }
 
     JSObject* options = constructEmptyObject(&exec);
     options->putDirect(vm, vm.propertyNames->locale, jsNontrivialString(&exec, m_locale));
@@ -217,8 +220,10 @@ JSObject* IntlPluralRules::resolvedOptions(ExecState& exec)
 #if HAVE(ICU_PLURALRULES_KEYWORDS)
     JSGlobalObject* globalObject = exec.jsCallee()->globalObject(vm);
     JSArray* categories = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
-    if (!categories)
-        return throwOutOfMemoryError(&exec, scope);
+    if (UNLIKELY(!categories)) {
+        throwOutOfMemoryError(&exec, scope);
+        return nullptr;
+    }
 
     UErrorCode status = U_ZERO_ERROR;
     auto keywords = std::unique_ptr<UEnumeration, UEnumerationDeleter>(uplrules_getKeywords(m_pluralRules.get(), &status));
index f0acc03..2435155 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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
@@ -128,8 +128,10 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
         if (lengthOpt)
             length = lengthOpt.value();
         else {
-            if ((buffer->byteLength() - offset) % ViewClass::elementSize)
-                return throwRangeError(exec, scope, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"_s);
+            if (UNLIKELY((buffer->byteLength() - offset) % ViewClass::elementSize)) {
+                throwRangeError(exec, scope, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"_s);
+                return nullptr;
+            }
             length = (buffer->byteLength() - offset) / ViewClass::elementSize;
         }
 
@@ -137,8 +139,10 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
     }
     ASSERT(!offset && !lengthOpt);
     
-    if (ViewClass::TypedArrayStorageType == TypeDataView)
-        return throwTypeError(exec, scope, "Expected ArrayBuffer for the first argument."_s);
+    if (UNLIKELY(ViewClass::TypedArrayStorageType == TypeDataView)) {
+        throwTypeError(exec, scope, "Expected ArrayBuffer for the first argument."_s);
+        return nullptr;
+    }
     
     // For everything but DataView, we allow construction with any of:
     // - Another array. This creates a copy of the of that array.
index e8194c8..0230661 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003-2018 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -58,6 +58,7 @@ inline JSCell* getJSFunction(JSValue value)
     return 0;
 }
 
+class Exception;
 class GetterSetter;
 class InternalFunction;
 class JSFunction;
@@ -70,7 +71,7 @@ class ThrowScope;
 struct HashTable;
 struct HashTableValue;
 
-JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, ThrowScope&, const String&);
+JS_EXPORT_PRIVATE Exception* throwTypeError(ExecState*, ThrowScope&, const String&);
 extern JS_EXPORT_PRIVATE const ASCIILiteral NonExtensibleObjectPropertyDefineError;
 extern JS_EXPORT_PRIVATE const ASCIILiteral ReadonlyPropertyWriteError;
 extern JS_EXPORT_PRIVATE const ASCIILiteral ReadonlyPropertyChangeError;
index c4a4905..baca820 100644 (file)
@@ -778,8 +778,10 @@ JSObject* objectConstructorSeal(ExecState* exec, JSObject* object)
 
     bool success = setIntegrityLevel<IntegrityLevel::Sealed>(exec, vm, object);
     RETURN_IF_EXCEPTION(scope, nullptr);
-    if (UNLIKELY(!success))
-        return throwTypeError(exec, scope, "Unable to prevent extension in Object.seal"_s);
+    if (UNLIKELY(!success)) {
+        throwTypeError(exec, scope, "Unable to prevent extension in Object.seal"_s);
+        return nullptr;
+    }
 
     return object;
 }
@@ -809,8 +811,10 @@ JSObject* objectConstructorFreeze(ExecState* exec, JSObject* object)
 
     bool success = setIntegrityLevel<IntegrityLevel::Frozen>(exec, vm, object);
     RETURN_IF_EXCEPTION(scope, nullptr);
-    if (!success)
-        return throwTypeError(exec, scope, "Unable to prevent extension in Object.freeze"_s);
+    if (UNLIKELY(!success)) {
+        throwTypeError(exec, scope, "Unable to prevent extension in Object.freeze"_s);
+        return nullptr;
+    }
     return object;
 }
 
index 5d72218..3578d2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-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
@@ -121,7 +121,7 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
         for (auto& entry : lexicalDeclarations) {
             // The ES6 spec says that RestrictedGlobalProperty can't be shadowed.
             GlobalPropertyLookUpStatus status = hasRestrictedGlobalProperty(exec, globalObject, entry.key.get());
-            RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+            RETURN_IF_EXCEPTION(throwScope, nullptr);
             switch (status) {
             case GlobalPropertyLookUpStatus::NonConfigurable:
                 return createSyntaxError(exec, makeString("Can't create duplicate variable that shadows a global property: '", String(entry.key.get()), "'"));
@@ -138,7 +138,7 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
             }
 
             bool hasProperty = globalLexicalEnvironment->hasProperty(exec, entry.key.get());
-            RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+            RETURN_IF_EXCEPTION(throwScope, nullptr);
             if (hasProperty) {
                 if (UNLIKELY(entry.value.isConst() && !vm.globalConstRedeclarationShouldThrow() && !isStrictMode())) {
                     // We only allow "const" duplicate declarations under this setting.
@@ -155,7 +155,7 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
         if (!globalLexicalEnvironment->isEmpty()) {
             for (auto& entry : variableDeclarations) {
                 bool hasProperty = globalLexicalEnvironment->hasProperty(exec, entry.key.get());
-                RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+                RETURN_IF_EXCEPTION(throwScope, nullptr);
                 if (hasProperty)
                     return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'"));
             }
index 16a45ad..96159ec 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007-2008, 2016 Apple Inc. All Rights Reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All Rights Reserved.
  *  Copyright (C) 2009 Torch Mobile, Inc.
  *
  *  This library is free software; you can redistribute it and/or
@@ -210,8 +210,10 @@ static JSObject* regExpCreate(ExecState* exec, JSGlobalObject* globalObject, JSV
         return nullptr;
 
     RegExp* regExp = RegExp::create(vm, pattern, flags);
-    if (!regExp->isValid())
-        return throwException(exec, scope, regExp->errorToThrow(exec));
+    if (UNLIKELY(!regExp->isValid())) {
+        throwException(exec, scope, regExp->errorToThrow(exec));
+        return nullptr;
+    }
 
     Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
     RETURN_IF_EXCEPTION(scope, nullptr);
@@ -250,8 +252,10 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A
                 return nullptr;
             regExp = RegExp::create(vm, regExp->pattern(), flags);
 
-            if (!regExp->isValid())
-                return throwException(exec, scope, regExp->errorToThrow(exec));
+            if (UNLIKELY(!regExp->isValid())) {
+                throwException(exec, scope, regExp->errorToThrow(exec));
+                return nullptr;
+            }
         }
 
         return RegExpObject::create(vm, structure, regExp);
index 115b178..65e872d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-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
@@ -252,7 +252,7 @@ bool ScriptExecutable::hasClearableCode(VM& vm) const
 }
 
 CodeBlock* ScriptExecutable::newCodeBlockFor(
-    CodeSpecializationKind kind, JSFunction* function, JSScope* scope, JSObject*& exception)
+    CodeSpecializationKind kind, JSFunction* function, JSScope* scope, Exception*& exception)
 {
     VM* vm = scope->vm();
     auto throwScope = DECLARE_THROW_SCOPE(*vm);
@@ -402,18 +402,18 @@ static void setupJIT(VM& vm, CodeBlock* codeBlock)
 #endif
 }
 
-JSObject* ScriptExecutable::prepareForExecutionImpl(
+Exception* ScriptExecutable::prepareForExecutionImpl(
     VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     DeferGCForAWhile deferGC(vm.heap);
 
-    if (vm.getAndClearFailNextNewCodeBlock()) {
+    if (UNLIKELY(vm.getAndClearFailNextNewCodeBlock())) {
         auto& state = *scope->globalObject(vm)->globalExec();
         return throwException(&state, throwScope, createError(&state, "Forced Failure"_s));
     }
 
-    JSObject* exception = nullptr;
+    Exception* exception = nullptr;
     CodeBlock* codeBlock = newCodeBlockFor(kind, function, scope, exception);
     resultCodeBlock = codeBlock;
     EXCEPTION_ASSERT(!!throwScope.exception() == !codeBlock);
index 115f883..bc33924 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-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
@@ -92,7 +92,7 @@ public:
 
     void installCode(CodeBlock*);
     void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind);
-    CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
+    CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, Exception*&);
     CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind);
 
     void clearCode(IsoCellSet&);
@@ -120,11 +120,11 @@ public:
     // to point to it. This forces callers to have a CodeBlock* in a register or on the stack that will be marked
     // by conservative GC if a GC happens after we create the CodeBlock.
     template <typename ExecutableType>
-    JSObject* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);
+    Exception* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);
 
 private:
     friend class ExecutableBase;
-    JSObject* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
+    Exception* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
 
     bool hasClearableCode(VM&) const;
 
index 97fbaa4..a1197c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -70,15 +70,15 @@ ThrowScope::~ThrowScope()
         simulateThrow();
 }
 
-void ThrowScope::throwException(ExecState* exec, Exception* exception)
+Exception* ThrowScope::throwException(ExecState* exec, Exception* exception)
 {
     if (m_vm.exception() && m_vm.exception() != exception)
         m_vm.verifyExceptionCheckNeedIsSatisfied(m_recursionDepth, m_location);
     
-    m_vm.throwException(exec, exception);
+    return m_vm.throwException(exec, exception);
 }
 
-JSValue ThrowScope::throwException(ExecState* exec, JSValue error)
+Exception* ThrowScope::throwException(ExecState* exec, JSValue error)
 {
     if (!error.isCell() || !jsDynamicCast<Exception*>(m_vm, error.asCell()))
         m_vm.verifyExceptionCheckNeedIsSatisfied(m_recursionDepth, m_location);
@@ -86,11 +86,9 @@ JSValue ThrowScope::throwException(ExecState* exec, JSValue error)
     return m_vm.throwException(exec, error);
 }
 
-JSObject* ThrowScope::throwException(ExecState* exec, JSObject* obj)
+Exception* ThrowScope::throwException(ExecState* exec, JSObject* obj)
 {
-    if (!jsDynamicCast<Exception*>(m_vm, obj))
-        m_vm.verifyExceptionCheckNeedIsSatisfied(m_recursionDepth, m_location);
-    
+    m_vm.verifyExceptionCheckNeedIsSatisfied(m_recursionDepth, m_location);
     return m_vm.throwException(exec, obj);
 }
 
index d283caf..e12bbe0 100644 (file)
@@ -47,9 +47,9 @@ public:
     ThrowScope(const ThrowScope&) = delete;
     ThrowScope(ThrowScope&&) = default;
 
-    JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*);
-    JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
-    JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, Exception*);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, JSObject*);
 
     void release() { m_isReleased = true; }
 
@@ -77,9 +77,9 @@ public:
     ThrowScope(const ThrowScope&) = delete;
     ThrowScope(ThrowScope&&) = default;
 
-    ALWAYS_INLINE void throwException(ExecState* exec, Exception* exception) { m_vm.throwException(exec, exception); }
-    ALWAYS_INLINE JSValue throwException(ExecState* exec, JSValue value) { return m_vm.throwException(exec, value); }
-    ALWAYS_INLINE JSObject* throwException(ExecState* exec, JSObject* obj) { return m_vm.throwException(exec, obj); }
+    ALWAYS_INLINE Exception* throwException(ExecState* exec, Exception* exception) { return m_vm.throwException(exec, exception); }
+    ALWAYS_INLINE Exception* throwException(ExecState* exec, JSValue value) { return m_vm.throwException(exec, value); }
+    ALWAYS_INLINE Exception* throwException(ExecState* exec, JSObject* obj) { return m_vm.throwException(exec, obj); }
 
     ALWAYS_INLINE void release() { }
 };
@@ -89,17 +89,17 @@ public:
 
 #endif // ENABLE(EXCEPTION_SCOPE_VERIFICATION)
 
-ALWAYS_INLINE void throwException(ExecState* exec, ThrowScope& scope, Exception* exception)
+ALWAYS_INLINE Exception* throwException(ExecState* exec, ThrowScope& scope, Exception* exception)
 {
-    scope.throwException(exec, exception);
+    return scope.throwException(exec, exception);
 }
 
-ALWAYS_INLINE JSValue throwException(ExecState* exec, ThrowScope& scope, JSValue value)
+ALWAYS_INLINE Exception* throwException(ExecState* exec, ThrowScope& scope, JSValue value)
 {
     return scope.throwException(exec, value);
 }
 
-ALWAYS_INLINE JSObject* throwException(ExecState* exec, ThrowScope& scope, JSObject* obj)
+ALWAYS_INLINE Exception* throwException(ExecState* exec, ThrowScope& scope, JSObject* obj)
 {
     return scope.throwException(exec, obj);
 }
index 31baa0f..1dcff7c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-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
@@ -811,7 +811,7 @@ void VM::clearSourceProviderCaches()
     sourceProviderCacheMap.clear();
 }
 
-void VM::throwException(ExecState* exec, Exception* exception)
+Exception* VM::throwException(ExecState* exec, Exception* exception)
 {
     ASSERT(exec == topCallFrame || exec->isGlobalExec() || exec == exec->lexicalGlobalObject()->callFrameAtDebuggerEntry());
     CallFrame* throwOriginFrame = exec->isGlobalExec() ? exec : topJSCallFrame();
@@ -830,22 +830,22 @@ void VM::throwException(ExecState* exec, Exception* exception)
     m_nativeStackTraceOfLastThrow = StackTrace::captureStackTrace(Options::unexpectedExceptionStackTraceLimit());
     m_throwingThread = &Thread::current();
 #endif
+    return exception;
 }
 
-JSValue VM::throwException(ExecState* exec, JSValue thrownValue)
+Exception* VM::throwException(ExecState* exec, JSValue thrownValue)
 {
     VM& vm = *this;
     Exception* exception = jsDynamicCast<Exception*>(vm, thrownValue);
     if (!exception)
         exception = Exception::create(*this, thrownValue);
 
-    throwException(exec, exception);
-    return JSValue(exception);
+    return throwException(exec, exception);
 }
 
-JSObject* VM::throwException(ExecState* exec, JSObject* error)
+Exception* VM::throwException(ExecState* exec, JSObject* error)
 {
-    return asObject(throwException(exec, JSValue(error)));
+    return throwException(exec, JSValue(error));
 }
 
 void VM::setStackPointerAtVMEntry(void* sp)
index aa04da1..432614b 100644 (file)
@@ -946,9 +946,9 @@ private:
     bool isSafeToRecurseSoftCLoop() const;
 #endif // ENABLE(C_LOOP)
 
-    JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*);
-    JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
-    JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, Exception*);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE Exception* throwException(ExecState*, JSObject*);
 
 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
     void verifyExceptionCheckNeedIsSatisfied(unsigned depth, ExceptionEventLocation&);
index 6956414..01ee655 100644 (file)
@@ -1,3 +1,17 @@
+2019-03-06  Mark Lam  <mark.lam@apple.com>
+
+        Exception is a JSCell, not a JSObject.
+        https://bugs.webkit.org/show_bug.cgi?id=195392
+
+        Reviewed by Saam Barati.
+
+        * bridge/objc/objc_utility.h:
+        * bridge/objc/objc_utility.mm:
+        (JSC::Bindings::throwError):
+        * bridge/runtime_object.cpp:
+        (JSC::Bindings::RuntimeObject::throwInvalidAccessError):
+        * bridge/runtime_object.h:
+
 2019-03-07  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: Canvas: lazily create the agent
index add4d9e..36acb61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004 Apple Inc.  All rights reserved.
+ * Copyright (C) 2004-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
@@ -74,7 +74,7 @@ JSValue convertNSStringToString(ExecState* exec, NSString *nsstring);
 JSValue convertObjcValueToValue(ExecState*, void* buffer, ObjcValueType, RootObject*);
 ObjcValueType objcValueTypeForType(const char *type);
 
-JSObject *throwError(ExecState*, ThrowScope&, NSString *message);
+Exception *throwError(ExecState*, ThrowScope&, NSString *message);
 
 } // namespace Bindings
 } // namespace JSC
index a4354bb..cb661ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2018 Apple Inc.  All rights reserved.
+ * Copyright (C) 2004-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
@@ -313,11 +313,10 @@ ObjcValueType objcValueTypeForType(const char *type)
     return objcValueType;
 }
 
-JSObject *throwError(ExecState *exec, ThrowScope& scope, NSString *message)
+Exception *throwError(ExecState *exec, ThrowScope& scope, NSString *message)
 {
     ASSERT(message);
-    JSObject *error = throwException(exec, scope, JSC::createError(exec, String(message)));
-    return error;
+    return throwException(exec, scope, JSC::createError(exec, String(message)));
 }
 
 }
index 6a7284f..873ba34 100644 (file)
@@ -292,7 +292,7 @@ void RuntimeObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Prope
     instance->end();
 }
 
-JSObject* RuntimeObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope)
+Exception* RuntimeObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope)
 {
     return throwException(exec, scope, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
 }
index 92d04fa..c14fa99 100644 (file)
@@ -59,7 +59,7 @@ public:
 
     Instance* getInternalInstance() const { return m_instance.get(); }
 
-    static JSObject* throwInvalidAccessError(ExecState*, ThrowScope&);
+    static Exception* throwInvalidAccessError(ExecState*, ThrowScope&);
 
     DECLARE_INFO;
 
index 2ddb820..1568117 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-06  Mark Lam  <mark.lam@apple.com>
+
+        Exception is a JSCell, not a JSObject.
+        https://bugs.webkit.org/show_bug.cgi?id=195392
+
+        Reviewed by Saam Barati.
+
+        * WebProcess/Plugins/Netscape/JSNPObject.cpp:
+        (WebKit::JSNPObject::throwInvalidAccessError):
+        * WebProcess/Plugins/Netscape/JSNPObject.h:
+
 2019-03-07  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r242354.
index ef5fbc0..078d27e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-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
@@ -523,7 +523,7 @@ EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue thisValu
     return JSValue::encode(JSNPMethod::create(exec, thisObj->globalObject(), propertyName.publicName(), npIdentifier));
 }
 
-JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope)
+JSC::Exception* JSNPObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope)
 {
     return throwException(exec, scope, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
 }
index 6f6747f..d23e69c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-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
@@ -104,7 +104,7 @@ private:
 
     static JSC::EncodedJSValue propertyGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
     static JSC::EncodedJSValue methodGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
-    static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*, JSC::ThrowScope&);
+    static JSC::Exception* throwInvalidAccessError(JSC::ExecState*, JSC::ThrowScope&);
 
     NPRuntimeObjectMap* m_objectMap;
     NPObject* m_npObject;