Title: [281939] trunk/Source/_javascript_Core
Revision
281939
Author
ross.kirsl...@sony.com
Date
2021-09-02 11:33:59 -0700 (Thu, 02 Sep 2021)

Log Message

[JSC] ScriptExecutable::newCodeBlockFor should handle exceptions more predictably
https://bugs.webkit.org/show_bug.cgi?id=229787

Reviewed by Mark Lam.

ScriptExecutable::newCodeBlockFor has four codepaths -- one for each of EvalExecutable, ProgramExecutable,
ModuleProgramExecutable, and FunctionExecutable. These all end up in bool CodeBlock::finishCreation(...),
but the first three overwrite the current exception with an OOM error while the last does not.
Furthermore, newCodeBlockFor handles exceptions via an out param, which is then returned by its single caller,
prepareForExecutionImpl.

Altogether, this results in some questionable checking of the returned exception against throwScope.exception()
at prepareForExecution's callsites in Interpreter and elsewhere.

This patch aims to make this exception handling clearer and more consistent by:
1. not overwriting an existing exception with an OOM error
2. doing away with the out param in favor of RETURN_IF_EXCEPTION

* bytecode/CodeBlock.h:
(JSC::ScriptExecutable::prepareForExecution):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeModuleProgram):
* interpreter/InterpreterInlines.h:
(JSC::Interpreter::execute):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::virtualForWithFunction):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/ScriptExecutable.cpp:
(JSC::ScriptExecutable::newCodeBlockFor):
(JSC::ScriptExecutable::prepareForExecutionImpl):
* runtime/ScriptExecutable.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (281938 => 281939)


--- trunk/Source/_javascript_Core/ChangeLog	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-09-02 18:33:59 UTC (rev 281939)
@@ -1,3 +1,46 @@
+2021-09-02  Ross Kirsling  <ross.kirsl...@sony.com>
+
+        [JSC] ScriptExecutable::newCodeBlockFor should handle exceptions more predictably
+        https://bugs.webkit.org/show_bug.cgi?id=229787
+
+        Reviewed by Mark Lam.
+
+        ScriptExecutable::newCodeBlockFor has four codepaths -- one for each of EvalExecutable, ProgramExecutable,
+        ModuleProgramExecutable, and FunctionExecutable. These all end up in bool CodeBlock::finishCreation(...),
+        but the first three overwrite the current exception with an OOM error while the last does not.
+        Furthermore, newCodeBlockFor handles exceptions via an out param, which is then returned by its single caller,
+        prepareForExecutionImpl.
+
+        Altogether, this results in some questionable checking of the returned exception against throwScope.exception()
+        at prepareForExecution's callsites in Interpreter and elsewhere.
+
+        This patch aims to make this exception handling clearer and more consistent by:
+        1. not overwriting an existing exception with an OOM error
+        2. doing away with the out param in favor of RETURN_IF_EXCEPTION
+
+        * bytecode/CodeBlock.h:
+        (JSC::ScriptExecutable::prepareForExecution):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeProgram):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeModuleProgram):
+        * interpreter/InterpreterInlines.h:
+        (JSC::Interpreter::execute):
+        * jit/JITOperations.cpp:
+        (JSC::JSC_DEFINE_JIT_OPERATION):
+        (JSC::virtualForWithFunction):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/ScriptExecutable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        (JSC::ScriptExecutable::prepareForExecutionImpl):
+        * runtime/ScriptExecutable.h:
+
 2021-09-02  Mikhail R. Gadelha  <mikh...@igalia.com>
 
         Fix IndexedDoubleStore InlineAccess for 32 bits

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (281938 => 281939)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2021-09-02 18:33:59 UTC (rev 281939)
@@ -1049,29 +1049,23 @@
 };
 
 template <typename ExecutableType>
-Exception* ScriptExecutable::prepareForExecution(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
+void ScriptExecutable::prepareForExecution(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
 {
     if (hasJITCodeFor(kind)) {
-        if constexpr (std::is_same<ExecutableType, EvalExecutable>::value) {
+        if constexpr (std::is_same<ExecutableType, EvalExecutable>::value)
             resultCodeBlock = jsCast<CodeBlock*>(jsCast<ExecutableType*>(this)->codeBlock());
-            return nullptr;
-        }
-        if constexpr (std::is_same<ExecutableType, ProgramExecutable>::value) {
+        else if constexpr (std::is_same<ExecutableType, ProgramExecutable>::value)
             resultCodeBlock = jsCast<CodeBlock*>(jsCast<ExecutableType*>(this)->codeBlock());
-            return nullptr;
-        }
-        if constexpr (std::is_same<ExecutableType, ModuleProgramExecutable>::value) {
+        else if constexpr (std::is_same<ExecutableType, ModuleProgramExecutable>::value)
             resultCodeBlock = jsCast<CodeBlock*>(jsCast<ExecutableType*>(this)->codeBlock());
-            return nullptr;
-        }
-        if constexpr (std::is_same<ExecutableType, FunctionExecutable>::value) {
+        else {
+            static_assert(std::is_same<ExecutableType, FunctionExecutable>::value);
             resultCodeBlock = jsCast<CodeBlock*>(jsCast<ExecutableType*>(this)->codeBlockFor(kind));
-            return nullptr;
         }
-        RELEASE_ASSERT_NOT_REACHED();
-        return nullptr;
+        return;
     }
-    return prepareForExecutionImpl(vm, function, scope, kind, resultCodeBlock);
+
+    prepareForExecutionImpl(vm, function, scope, kind, resultCodeBlock);
 }
 
 #define CODEBLOCK_LOG_EVENT(codeBlock, summary, details) \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (281938 => 281939)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-02 18:33:59 UTC (rev 281939)
@@ -3763,13 +3763,11 @@
         codePtr = executable->entrypointFor(kind, MustCheckArity);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
+        RELEASE_ASSERT(isCall(kind) || functionExecutable->constructAbility() != ConstructAbility::CannotConstruct);
 
-        RELEASE_ASSERT(isCall(kind) || functionExecutable->constructAbility() != ConstructAbility::CannotConstruct);
-        
-        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, codeBlock);
-        EXCEPTION_ASSERT_UNUSED(throwScope, throwScope.exception() == error);
-        if (UNLIKELY(error))
-            return;
+        functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, codeBlock);
+        RETURN_IF_EXCEPTION(throwScope, void());
+
         unsigned argumentStackSlots = callLinkInfo->maxArgumentCountIncludingThis();
         if (argumentStackSlots < static_cast<size_t>(codeBlock->numParameters()))
             codePtr = functionExecutable->entrypointFor(kind, MustCheckArity);

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (281938 => 281939)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2021-09-02 18:33:59 UTC (rev 281939)
@@ -814,12 +814,11 @@
     ProgramCodeBlock* codeBlock;
     {
         CodeBlock* tempCodeBlock;
-        Exception* error = program->prepareForExecution<ProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == error);
-        if (UNLIKELY(error))
-            return checkedReturn(error);
+        program->prepareForExecution<ProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+
         codeBlock = jsCast<ProgramCodeBlock*>(tempCodeBlock);
-        ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
+        ASSERT(codeBlock && codeBlock->numParameters() == 1); // 1 parameter for 'this'.
     }
 
     RefPtr<JITCode> jitCode;
@@ -877,12 +876,10 @@
     CodeBlock* newCodeBlock = nullptr;
     if (isJSCall) {
         // Compile the callee:
-        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);
+        callData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(function), scope, CodeForCall, newCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
 
-        ASSERT(!!newCodeBlock);
+        ASSERT(newCodeBlock);
         newCodeBlock->m_shouldAlwaysBeInlined = false;
     }
 
@@ -955,12 +952,10 @@
     CodeBlock* newCodeBlock = nullptr;
     if (isJSConstruct) {
         // Compile the callee:
-        Exception* compileError = constructData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(constructor), scope, CodeForConstruct, newCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == compileError);
-        if (UNLIKELY(!!compileError))
-            return nullptr;
+        constructData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, jsCast<JSFunction*>(constructor), scope, CodeForConstruct, newCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, nullptr);
 
-        ASSERT(!!newCodeBlock);
+        ASSERT(newCodeBlock);
         newCodeBlock->m_shouldAlwaysBeInlined = false;
     }
 
@@ -995,16 +990,16 @@
     VM& vm = scope->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     throwScope.assertNoException();
-    
+
     if (vm.isCollectorBusyOnCurrentThread())
-        return CallFrameClosure();
+        return { };
 
     // Compile the callee:
     CodeBlock* newCodeBlock;
-    Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, function, scope, CodeForCall, newCodeBlock);
-    EXCEPTION_ASSERT(throwScope.exception() == error);
-    if (UNLIKELY(error))
-        return CallFrameClosure();
+    functionExecutable->prepareForExecution<FunctionExecutable>(vm, function, scope, CodeForCall, newCodeBlock);
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    ASSERT(newCodeBlock);
     newCodeBlock->m_shouldAlwaysBeInlined = false;
 
     size_t argsCount = argumentCountIncludingThis;
@@ -1066,23 +1061,14 @@
             return throwScope.exception();
     }
 
-    auto loadCodeBlock = [&](Exception*& compileError) -> EvalCodeBlock* {
+    EvalCodeBlock* codeBlock;
+    {
         CodeBlock* tempCodeBlock;
-        compileError = eval->prepareForExecution<EvalExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == compileError);
-        if (UNLIKELY(!!compileError))
-            return nullptr;
-        return jsCast<EvalCodeBlock*>(tempCodeBlock);
-    };
+        eval->prepareForExecution<EvalExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
 
-    EvalCodeBlock* codeBlock;
-    {
-        Exception* compileError = nullptr;
-        codeBlock = loadCodeBlock(compileError);
-        EXCEPTION_ASSERT(throwScope.exception() == compileError);
-        if (UNLIKELY(!!compileError))
-            return checkedReturn(compileError);
-        ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
+        codeBlock = jsCast<EvalCodeBlock*>(tempCodeBlock);
+        ASSERT(codeBlock && codeBlock->numParameters() == 1); // 1 parameter for 'this'.
     }
     UnlinkedEvalCodeBlock* unlinkedCodeBlock = codeBlock->unlinkedEvalCodeBlock();
 
@@ -1173,12 +1159,12 @@
 
     // Reload CodeBlock. It is possible that we replaced CodeBlock while setting up the environment.
     {
-        Exception* compileError = nullptr;
-        codeBlock = loadCodeBlock(compileError);
-        EXCEPTION_ASSERT(throwScope.exception() == compileError);
-        if (UNLIKELY(!!compileError))
-            return checkedReturn(compileError);
-        ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
+        CodeBlock* tempCodeBlock;
+        eval->prepareForExecution<EvalExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+
+        codeBlock = jsCast<EvalCodeBlock*>(tempCodeBlock);
+        ASSERT(codeBlock && codeBlock->numParameters() == 1); // 1 parameter for 'this'.
     }
 
     RefPtr<JITCode> jitCode;
@@ -1231,12 +1217,11 @@
     ModuleProgramCodeBlock* codeBlock;
     {
         CodeBlock* tempCodeBlock;
-        Exception* compileError = executable->prepareForExecution<ModuleProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
-        EXCEPTION_ASSERT(throwScope.exception() == compileError);
-        if (UNLIKELY(!!compileError))
-            return checkedReturn(compileError);
+        executable->prepareForExecution<ModuleProgramExecutable>(vm, nullptr, scope, CodeForCall, tempCodeBlock);
+        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+
         codeBlock = jsCast<ModuleProgramCodeBlock*>(tempCodeBlock);
-        ASSERT(codeBlock->numParameters() == numberOfArguments + 1);
+        ASSERT(codeBlock && codeBlock->numParameters() == numberOfArguments + 1);
     }
 
     RefPtr<JITCode> jitCode;

Modified: trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h (281938 => 281939)


--- trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h	2021-09-02 18:33:59 UTC (rev 281939)
@@ -88,10 +88,10 @@
 
     // Reload CodeBlock since GC can replace CodeBlock owned by Executable.
     CodeBlock* codeBlock;
-    Exception* error = closure.functionExecutable->prepareForExecution<FunctionExecutable>(vm, closure.function, closure.scope, CodeForCall, codeBlock);
-    EXCEPTION_ASSERT(throwScope.exception() == error);
-    if (UNLIKELY(error))
-        return checkedReturn(error);
+    closure.functionExecutable->prepareForExecution<FunctionExecutable>(vm, closure.function, closure.scope, CodeForCall, codeBlock);
+    RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+
+    ASSERT(codeBlock);
     codeBlock->m_shouldAlwaysBeInlined = false;
     {
         DisallowGC disallowGC; // Ensure no GC happens. GC can replace CodeBlock in Executable.

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (281938 => 281939)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2021-09-02 18:33:59 UTC (rev 281939)
@@ -1560,11 +1560,12 @@
         }
 
         CodeBlock** codeBlockSlot = calleeFrame->addressOfCodeBlock();
-        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
-        EXCEPTION_ASSERT(throwScope.exception() == error);
-        if (UNLIKELY(error))
-            return handleThrowException();
+        functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
+        RETURN_IF_EXCEPTION(throwScope, handleThrowException());
+
         codeBlock = *codeBlockSlot;
+        ASSERT(codeBlock);
+
         ArityCheckMode arity;
         if (calleeFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->isVarargs())
             arity = MustCheckArity;
@@ -1607,21 +1608,19 @@
     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 
+        auto handleThrowException = [&] () {
+            void* throwTarget = vm.getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress();
+            return encodeResult(throwTarget, reinterpret_cast<void*>(KeepTheFrame));
+        };
+
         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
             throwException(globalObject, throwScope, createNotAConstructorError(globalObject, function));
-            return encodeResult(
-                vm.getCTIStub(throwExceptionFromCallSlowPathGenerator).retaggedCode<JSEntryPtrTag>().executableAddress(),
-                reinterpret_cast<void*>(KeepTheFrame));
+            return handleThrowException();
         }
 
         CodeBlock** codeBlockSlot = calleeFrame->addressOfCodeBlock();
-        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));
-        }
+        functionExecutable->prepareForExecution<FunctionExecutable>(vm, function, scope, kind, *codeBlockSlot);
+        RETURN_IF_EXCEPTION(throwScope, handleThrowException());
     }
     // FIXME: Support wasm IC.
     // https://bugs.webkit.org/show_bug.cgi?id=220339

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (281938 => 281939)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2021-09-02 18:33:59 UTC (rev 281939)
@@ -1873,17 +1873,16 @@
         codePtr = executable->entrypointFor(kind, MustCheckArity);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-
         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
             LLINT_CALL_THROW(globalObject, createNotAConstructorError(globalObject, callee));
 
         CodeBlock** codeBlockSlot = calleeFrame->addressOfCodeBlock();
-        Exception* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
-        EXCEPTION_ASSERT(throwScope.exception() == error);
-        if (UNLIKELY(error))
-            LLINT_CALL_THROW(globalObject, error);
+        functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
+        LLINT_CALL_CHECK_EXCEPTION(globalObject);
+
         codeBlock = *codeBlockSlot;
         ASSERT(codeBlock);
+
         ArityCheckMode arity;
         if (calleeFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
             arity = MustCheckArity;

Modified: trunk/Source/_javascript_Core/runtime/ScriptExecutable.cpp (281938 => 281939)


--- trunk/Source/_javascript_Core/runtime/ScriptExecutable.cpp	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/runtime/ScriptExecutable.cpp	2021-09-02 18:33:59 UTC (rev 281939)
@@ -246,8 +246,7 @@
     return false;
 }
 
-CodeBlock* ScriptExecutable::newCodeBlockFor(
-    CodeSpecializationKind kind, JSFunction* function, JSScope* scope, Exception*& exception)
+CodeBlock* ScriptExecutable::newCodeBlockFor(CodeSpecializationKind kind, JSFunction* function, JSScope* scope)
 {
     VM& vm = scope->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -262,33 +261,15 @@
         RELEASE_ASSERT(kind == CodeForCall);
         RELEASE_ASSERT(!executable->m_evalCodeBlock);
         RELEASE_ASSERT(!function);
-        auto* codeBlock = EvalCodeBlock::create(vm,
-            executable, executable->m_unlinkedEvalCodeBlock.get(), scope);
-        EXCEPTION_ASSERT(throwScope.exception() || codeBlock);
-        if (!codeBlock) {
-            exception = throwException(
-                globalObject, throwScope,
-                createOutOfMemoryError(globalObject));
-            return nullptr;
-        }
-        return codeBlock;
+        RELEASE_AND_RETURN(throwScope, EvalCodeBlock::create(vm, executable, executable->m_unlinkedEvalCodeBlock.get(), scope));
     }
-    
+
     if (classInfo(vm) == ProgramExecutable::info()) {
         ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
         RELEASE_ASSERT(kind == CodeForCall);
         RELEASE_ASSERT(!executable->m_programCodeBlock);
         RELEASE_ASSERT(!function);
-        auto* codeBlock = ProgramCodeBlock::create(vm,
-            executable, executable->m_unlinkedProgramCodeBlock.get(), scope);
-        EXCEPTION_ASSERT(throwScope.exception() || codeBlock);
-        if (!codeBlock) {
-            exception = throwException(
-                globalObject, throwScope,
-                createOutOfMemoryError(globalObject));
-            return nullptr;
-        }
-        return codeBlock;
+        RELEASE_AND_RETURN(throwScope, ProgramCodeBlock::create(vm, executable, executable->m_unlinkedProgramCodeBlock.get(), scope));
     }
 
     if (classInfo(vm) == ModuleProgramExecutable::info()) {
@@ -296,16 +277,7 @@
         RELEASE_ASSERT(kind == CodeForCall);
         RELEASE_ASSERT(!executable->m_moduleProgramCodeBlock);
         RELEASE_ASSERT(!function);
-        auto* codeBlock = ModuleProgramCodeBlock::create(vm,
-            executable, executable->m_unlinkedModuleProgramCodeBlock.get(), scope);
-        EXCEPTION_ASSERT(throwScope.exception() || codeBlock);
-        if (!codeBlock) {
-            exception = throwException(
-                globalObject, throwScope,
-                createOutOfMemoryError(globalObject));
-            return nullptr;
-        }
-        return codeBlock;
+        RELEASE_AND_RETURN(throwScope, ModuleProgramCodeBlock::create(vm, executable, executable->m_unlinkedModuleProgramCodeBlock.get(), scope));
     }
 
     RELEASE_ASSERT(classInfo(vm) == FunctionExecutable::info());
@@ -333,16 +305,11 @@
         executable->m_unlinkedExecutable->hasCapturedVariables(),
         lastLine(), endColumn()); 
     if (!unlinkedCodeBlock) {
-        exception = throwException(
-            globalObject, throwScope,
-            error.toErrorObject(globalObject, executable->source()));
+        throwException(globalObject, throwScope, error.toErrorObject(globalObject, executable->source()));
         return nullptr;
     }
 
-    auto* codeBlock = FunctionCodeBlock::create(vm, executable, unlinkedCodeBlock, scope);
-    if (throwScope.exception())
-        exception = throwScope.exception();
-    return codeBlock;
+    RELEASE_AND_RETURN(throwScope, FunctionCodeBlock::create(vm, executable, unlinkedCodeBlock, scope));
 }
 
 CodeBlock* ScriptExecutable::newReplacementCodeBlockFor(
@@ -409,8 +376,7 @@
 #endif
 }
 
-Exception* ScriptExecutable::prepareForExecutionImpl(
-    VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
+void ScriptExecutable::prepareForExecutionImpl(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     DeferGCForAWhile deferGC(vm.heap);
@@ -417,26 +383,25 @@
 
     if (UNLIKELY(vm.getAndClearFailNextNewCodeBlock())) {
         JSGlobalObject* globalObject = scope->globalObject(vm);
-        return throwException(globalObject, throwScope, createError(globalObject, "Forced Failure"_s));
+        throwException(globalObject, throwScope, createError(globalObject, "Forced Failure"_s));
+        return;
     }
 
-    Exception* exception = nullptr;
-    CodeBlock* codeBlock = newCodeBlockFor(kind, function, scope, exception);
+    CodeBlock* codeBlock = newCodeBlockFor(kind, function, scope);
+    RETURN_IF_EXCEPTION(throwScope, void());
+
+    ASSERT(codeBlock);
     resultCodeBlock = codeBlock;
-    EXCEPTION_ASSERT(!!throwScope.exception() == !codeBlock);
-    if (UNLIKELY(!codeBlock))
-        return exception;
-    
+
     if (Options::validateBytecode())
         codeBlock->validate();
-    
+
     if (Options::useLLInt())
         setupLLInt(codeBlock);
     else
         setupJIT(vm, codeBlock);
-    
+
     installCode(vm, codeBlock, codeBlock->codeType(), codeBlock->specializationKind());
-    return nullptr;
 }
 
 ScriptExecutable* ScriptExecutable::topLevelExecutable()

Modified: trunk/Source/_javascript_Core/runtime/ScriptExecutable.h (281938 => 281939)


--- trunk/Source/_javascript_Core/runtime/ScriptExecutable.h	2021-09-02 18:31:12 UTC (rev 281938)
+++ trunk/Source/_javascript_Core/runtime/ScriptExecutable.h	2021-09-02 18:33:59 UTC (rev 281939)
@@ -88,7 +88,7 @@
     void recordParse(CodeFeatures, LexicalScopeFeatures, bool hasCapturedVariables, int lastLine, unsigned endColumn);
     void installCode(CodeBlock*);
     void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind);
-    CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, Exception*&);
+    CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*);
     CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind);
 
     void clearCode(IsoCellSet&);
@@ -114,7 +114,7 @@
     // 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>
-    Exception* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);
+    void prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
 
     ScriptExecutable* topLevelExecutable();
     JSArray* createTemplateObject(JSGlobalObject*, JSTemplateObjectDescriptor*);
@@ -121,7 +121,7 @@
 
 private:
     friend class ExecutableBase;
-    Exception* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
+    void prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
 
     bool hasClearableCode(VM&) const;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to