[WTF] Import std::optional reference implementation as WTF::Optional
[WebKit-https.git] / Source / JavaScriptCore / debugger / DebuggerCallFrame.cpp
index 8dc7e8f..7f82127 100644 (file)
@@ -62,6 +62,12 @@ private:
 
 Ref<DebuggerCallFrame> DebuggerCallFrame::create(CallFrame* callFrame)
 {
+    if (UNLIKELY(callFrame == callFrame->lexicalGlobalObject()->globalExec())) {
+        ShadowChicken::Frame emptyFrame;
+        RELEASE_ASSERT(!emptyFrame.isTailDeleted);
+        return adoptRef(*new DebuggerCallFrame(callFrame, emptyFrame));
+    }
+
     Vector<ShadowChicken::Frame> frames;
     callFrame->vm().shadowChicken().iterate(callFrame->vm(), callFrame, [&] (const ShadowChicken::Frame& frame) -> bool {
         frames.append(frame);
@@ -69,16 +75,15 @@ Ref<DebuggerCallFrame> DebuggerCallFrame::create(CallFrame* callFrame)
     });
 
     RELEASE_ASSERT(frames.size());
-    RELEASE_ASSERT(!frames[0].isTailDeleted); // The top frame should never be tail deleted.
-    RELEASE_ASSERT(!frames[frames.size() - 1].isTailDeleted); // The first frame should never be tail deleted.
+    ASSERT(!frames[0].isTailDeleted); // The top frame should never be tail deleted.
 
     RefPtr<DebuggerCallFrame> currentParent = nullptr;
-    ExecState* exec = nullptr;
+    ExecState* exec = callFrame->lexicalGlobalObject()->globalExec();
+    // This walks the stack from the entry stack frame to the top of the stack.
     for (unsigned i = frames.size(); i--; ) {
         const ShadowChicken::Frame& frame = frames[i];
         if (!frame.isTailDeleted)
             exec = frame.frame;
-        ASSERT(exec);
         Ref<DebuggerCallFrame> currentFrame = adoptRef(*new DebuggerCallFrame(exec, frame));
         currentFrame->m_caller = currentParent;
         currentParent = WTFMove(currentFrame);
@@ -133,7 +138,7 @@ String DebuggerCallFrame::functionName() const
 
     if (isTailDeleted()) {
         if (JSFunction* func = jsDynamicCast<JSFunction*>(m_shadowChickenFrame.callee))
-            return func->calculatedDisplayName(m_validMachineFrame);
+            return func->calculatedDisplayName(m_validMachineFrame->vm());
         return m_shadowChickenFrame.codeBlock->inferredName().data();
     }
 
@@ -212,7 +217,9 @@ JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSOb
     if (!callFrame)
         return jsUndefined();
 
-    JSLockHolder lock(callFrame);
+    VM& vm = callFrame->vm();
+    JSLockHolder lock(vm);
+    auto catchScope = DECLARE_CATCH_SCOPE(vm);
 
     CodeBlock* codeBlock = nullptr;
     if (isTailDeleted())
@@ -223,8 +230,6 @@ JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSOb
         return jsUndefined();
     
     DebuggerEvalEnabler evalEnabler(callFrame);
-    VM& vm = callFrame->vm();
-    ThisTDZMode thisTDZMode = codeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
 
     EvalContextType evalContextType;
     
@@ -236,12 +241,12 @@ JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSOb
         evalContextType = EvalContextType::None;
 
     VariableEnvironment variablesUnderTDZ;
-    JSScope::collectVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ);
+    JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ);
 
-    EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), thisTDZMode, codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ);
-    if (vm.exception()) {
-        exception = vm.exception();
-        vm.clearException();
+    EvalExecutable* eval = DirectEvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ);
+    if (UNLIKELY(catchScope.exception())) {
+        exception = catchScope.exception();
+        catchScope.clearException();
         return jsUndefined();
     }
 
@@ -253,9 +258,9 @@ JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSOb
 
     JSValue thisValue = this->thisValue();
     JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope());
-    if (vm.exception()) {
-        exception = vm.exception();
-        vm.clearException();
+    if (UNLIKELY(catchScope.exception())) {
+        exception = catchScope.exception();
+        catchScope.clearException();
     }
 
     if (scopeExtensionObject)
@@ -274,7 +279,7 @@ void DebuggerCallFrame::invalidate()
             frame->m_scope->invalidateChain();
             frame->m_scope.clear();
         }
-        frame = frame->m_caller.release();
+        frame = WTFMove(frame->m_caller);
     }
 }
 
@@ -285,7 +290,7 @@ TextPosition DebuggerCallFrame::currentPosition()
 
     if (isTailDeleted()) {
         CodeBlock* codeBlock = m_shadowChickenFrame.codeBlock;
-        if (Optional<unsigned> bytecodeOffset = codeBlock->bytecodeOffsetFromCallSiteIndex(m_shadowChickenFrame.callSiteIndex)) {
+        if (std::optional<unsigned> bytecodeOffset = codeBlock->bytecodeOffsetFromCallSiteIndex(m_shadowChickenFrame.callSiteIndex)) {
             return TextPosition(OrdinalNumber::fromOneBasedInt(codeBlock->lineNumberForBytecodeOffset(*bytecodeOffset)),
                 OrdinalNumber::fromOneBasedInt(codeBlock->columnNumberForBytecodeOffset(*bytecodeOffset)));
         }