Move vmEntryGlobalObject() to VM from CallFrame.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Aug 2018 22:57:09 +0000 (22:57 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Aug 2018 22:57:09 +0000 (22:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188900
<rdar://problem/43655753>

Reviewed by Michael Saboff.

Source/JavaScriptCore:

Also introduced CallFrame::isGlobalExec() which makes use of one property of
GlobalExecs to identify them i.e. GlobalExecs have null callerFrame and returnPCs.
CallFrame::initGlobalExec() ensures this.

In contrast, normal CallFrames always have a callerFrame (because they must at
least be preceded by a VM EntryFrame) and a returnPC (at least return to the
VM entry glue).

* API/APIUtils.h:
(handleExceptionIfNeeded):
(setException):
* API/JSBase.cpp:
(JSEvaluateScript):
(JSCheckScriptSyntax):
* API/JSContextRef.cpp:
(JSGlobalContextRetain):
(JSGlobalContextRelease):
(JSGlobalContextCopyName):
(JSGlobalContextSetName):
(JSGlobalContextGetRemoteInspectionEnabled):
(JSGlobalContextSetRemoteInspectionEnabled):
(JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions):
(JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions):
(JSGlobalContextGetDebuggerRunLoop):
(JSGlobalContextSetDebuggerRunLoop):
(JSGlobalContextGetAugmentableInspectorController):
* API/JSValue.mm:
(reportExceptionToInspector):
* API/glib/JSCClass.cpp:
(jscContextForObject):
* API/glib/JSCContext.cpp:
(jsc_context_evaluate_in_object):
* debugger/Debugger.cpp:
(JSC::Debugger::pauseIfNeeded):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::vmEntryGlobalObject const):
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::vmEntryGlobalObject): Deleted.
* interpreter/CallFrame.h:
(JSC::ExecState::scope const):
(JSC::ExecState::noCaller):
(JSC::ExecState::isGlobalExec const):
* interpreter/Interpreter.cpp:
(JSC::notifyDebuggerOfUnwinding):
(JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):
(JSC::Interpreter::debug):
* runtime/CallData.cpp:
(JSC::profiledCall):
* runtime/Completion.cpp:
(JSC::evaluate):
(JSC::profiledEvaluate):
(JSC::evaluateWithScopeExtension):
(JSC::loadAndEvaluateModule):
(JSC::loadModule):
(JSC::linkAndEvaluateModule):
(JSC::importModule):
* runtime/ConstructData.cpp:
(JSC::profiledConstruct):
* runtime/Error.cpp:
(JSC::getStackTrace):
* runtime/VM.cpp:
(JSC::VM::throwException):
(JSC::VM::vmEntryGlobalObject const):
* runtime/VM.h:

Source/WebCore:

No new tests needed because this patch does not introduce new functionality.

* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::create):
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::callerGlobalObject):
(WebCore::toJSDOMGlobalObject): Deleted.
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::firstDOMWindow):
* bridge/c/c_utility.cpp:
(JSC::Bindings::convertValueToNPVariant):
* bridge/objc/WebScriptObject.mm:
(WebCore::addExceptionToConsole):
* bridge/objc/objc_instance.mm:
(ObjcInstance::moveGlobalExceptionToExecState):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::convertValueToObjcObject):
* bridge/objc/objc_utility.mm:
(JSC::Bindings::convertValueToObjcValue):
* testing/Internals.cpp:
(WebCore::Internals::cloneArrayBuffer):

Source/WebKitLegacy/mac:

* WebView/WebScriptDebugger.mm:
(WebScriptDebugger::sourceParsed):

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

30 files changed:
Source/JavaScriptCore/API/APIUtils.h
Source/JavaScriptCore/API/JSBase.cpp
Source/JavaScriptCore/API/JSContextRef.cpp
Source/JavaScriptCore/API/JSValue.mm
Source/JavaScriptCore/API/glib/JSCClass.cpp
Source/JavaScriptCore/API/glib/JSCContext.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/debugger/Debugger.cpp
Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
Source/JavaScriptCore/interpreter/CallFrame.cpp
Source/JavaScriptCore/interpreter/CallFrame.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/runtime/CallData.cpp
Source/JavaScriptCore/runtime/Completion.cpp
Source/JavaScriptCore/runtime/ConstructData.cpp
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bridge/c/c_utility.cpp
Source/WebCore/bridge/objc/WebScriptObject.mm
Source/WebCore/bridge/objc/objc_instance.mm
Source/WebCore/bridge/objc/objc_runtime.mm
Source/WebCore/bridge/objc/objc_utility.mm
Source/WebCore/testing/Internals.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebScriptDebugger.mm

index 56828ed..2726396 100644 (file)
@@ -45,7 +45,7 @@ inline ExceptionStatus handleExceptionIfNeeded(JSC::CatchScope& scope, JSC::Exec
             *returnedExceptionRef = toRef(exec, exception->value());
         scope.clearException();
 #if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+        scope.vm().vmEntryGlobalObject(exec)->inspectorController().reportAPIException(exec, exception);
 #endif
         return ExceptionStatus::DidThrow;
     }
@@ -57,7 +57,8 @@ inline void setException(JSC::ExecState* exec, JSValueRef* returnedExceptionRef,
     if (returnedExceptionRef)
         *returnedExceptionRef = toRef(exec, exception);
 #if ENABLE(REMOTE_INSPECTOR)
-    exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, JSC::Exception::create(exec->vm(), exception));
+    VM& vm = exec->vm();
+    vm.vmEntryGlobalObject(exec)->inspectorController().reportAPIException(exec, JSC::Exception::create(vm, exception));
 #endif
 }
 
index 4c0597d..1329a80 100644 (file)
@@ -54,14 +54,15 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
         return 0;
     }
     ExecState* exec = toJS(ctx);
-    JSLockHolder locker(exec);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
 
     JSObject* jsThisObject = toJS(thisObject);
 
     startingLineNumber = std::max(1, startingLineNumber);
 
     // evaluate sets "this" to the global object if it is NULL
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
     auto sourceURLString = sourceURL ? sourceURL->string() : String();
     SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()));
 
@@ -105,14 +106,14 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()));
     
     JSValue syntaxException;
-    bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
+    bool isValidSyntax = checkSyntax(vm.vmEntryGlobalObject(exec)->globalExec(), source, &syntaxException);
 
     if (!isValidSyntax) {
         if (exception)
             *exception = toRef(exec, syntaxException);
 #if ENABLE(REMOTE_INSPECTOR)
         Exception* exception = Exception::create(vm, syntaxException);
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+        vm.vmEntryGlobalObject(exec)->inspectorController().reportAPIException(exec, exception);
 #endif
         return false;
     }
index 025eba4..f3c0fd1 100644 (file)
@@ -162,10 +162,10 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
 JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
 {
     ExecState* exec = toJS(ctx);
-    JSLockHolder locker(exec);
-
     VM& vm = exec->vm();
-    gcProtect(exec->vmEntryGlobalObject());
+    JSLockHolder locker(vm);
+
+    gcProtect(vm.vmEntryGlobalObject(exec));
     vm.ref();
     return ctx;
 }
@@ -173,10 +173,10 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
 void JSGlobalContextRelease(JSGlobalContextRef ctx)
 {
     ExecState* exec = toJS(ctx);
-    JSLockHolder locker(exec);
-
     VM& vm = exec->vm();
-    bool protectCountIsZero = Heap::heap(exec->vmEntryGlobalObject())->unprotect(exec->vmEntryGlobalObject());
+    JSLockHolder locker(vm);
+
+    bool protectCountIsZero = vm.heap.unprotect(vm.vmEntryGlobalObject(exec));
     if (protectCountIsZero)
         vm.heap.reportAbandonedObjectGraph();
     vm.deref();
@@ -225,9 +225,10 @@ JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx)
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder locker(exec);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
 
-    String name = exec->vmEntryGlobalObject()->name();
+    String name = vm.vmEntryGlobalObject(exec)->name();
     if (name.isNull())
         return 0;
 
@@ -242,9 +243,10 @@ void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name)
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder locker(exec);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
 
-    exec->vmEntryGlobalObject()->setName(name ? name->string() : String());
+    vm.vmEntryGlobalObject(exec)->setName(name ? name->string() : String());
 }
 
 
@@ -325,9 +327,10 @@ bool JSGlobalContextGetRemoteInspectionEnabled(JSGlobalContextRef ctx)
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    return exec->vmEntryGlobalObject()->remoteDebuggingEnabled();
+    return vm.vmEntryGlobalObject(exec)->remoteDebuggingEnabled();
 }
 
 void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enabled)
@@ -338,9 +341,10 @@ void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enab
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    exec->vmEntryGlobalObject()->setRemoteDebuggingEnabled(enabled);
+    vm.vmEntryGlobalObject(exec)->setRemoteDebuggingEnabled(enabled);
 }
 
 bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx)
@@ -352,9 +356,10 @@ bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalCo
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
     return globalObject->inspectorController().includesNativeCallStackWhenReportingExceptions();
 #else
     UNUSED_PARAM(ctx);
@@ -371,9 +376,10 @@ void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalCo
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
     globalObject->inspectorController().setIncludesNativeCallStackWhenReportingExceptions(includesNativeCallStack);
 #else
     UNUSED_PARAM(ctx);
@@ -391,9 +397,10 @@ CFRunLoopRef JSGlobalContextGetDebuggerRunLoop(JSGlobalContextRef ctx)
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    return exec->vmEntryGlobalObject()->inspectorDebuggable().targetRunLoop();
+    return vm.vmEntryGlobalObject(exec)->inspectorDebuggable().targetRunLoop();
 #else
     UNUSED_PARAM(ctx);
     return nullptr;
@@ -409,9 +416,10 @@ void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef runL
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    exec->vmEntryGlobalObject()->inspectorDebuggable().setTargetRunLoop(runLoop);
+    vm.vmEntryGlobalObject(exec)->inspectorDebuggable().setTargetRunLoop(runLoop);
 #else
     UNUSED_PARAM(ctx);
     UNUSED_PARAM(runLoop);
@@ -428,8 +436,9 @@ Inspector::AugmentableInspectorController* JSGlobalContextGetAugmentableInspecto
     }
 
     ExecState* exec = toJS(ctx);
-    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
 
-    return &exec->vmEntryGlobalObject()->inspectorController();
+    return &vm.vmEntryGlobalObject(exec)->inspectorController();
 }
 #endif
index 417cc9d..df45fc0 100644 (file)
@@ -674,8 +674,9 @@ JSContainerConvertor::Task JSContainerConvertor::take()
 static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exceptionValue)
 {
     JSC::ExecState* exec = toJS(context);
-    JSC::Exception* exception = JSC::Exception::create(exec->vm(), exceptionValue);
-    exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+    JSC::VM& vm = exec->vm();
+    JSC::Exception* exception = JSC::Exception::create(vm, exceptionValue);
+    vm.vmEntryGlobalObject(exec)->inspectorController().reportAPIException(exec, exception);
 }
 #endif
 
index 95e2a0c..652928e 100644 (file)
@@ -128,9 +128,11 @@ static JSClassRef wrappedObjectClass(JSC::JSObject* jsObject)
 static GRefPtr<JSCContext> jscContextForObject(JSC::JSObject* jsObject)
 {
     ASSERT(isWrappedObject(jsObject));
-    JSC::ExecState* exec = jsObject->globalObject()->globalExec();
+    JSC::JSGlobalObject* globalObject = jsObject->globalObject();
+    JSC::ExecState* exec = globalObject->globalExec();
     if (jsObject->isGlobalObject()) {
-        if (auto* globalScopeExtension = exec->vmEntryGlobalObject()->globalScopeExtension())
+        JSC::VM& vm = globalObject->vm();
+        if (auto* globalScopeExtension = vm.vmEntryGlobalObject(exec)->globalScopeExtension())
             exec = JSC::JSScope::objectAtScope(globalScopeExtension)->globalObject()->globalExec();
     }
     return jscContextGetOrCreate(toGlobalRef(exec));
index e21c565..b548efb 100644 (file)
@@ -880,8 +880,9 @@ JSCValue* jsc_context_evaluate_in_object(JSCContext* context, const char* code,
     JSRetainPtr<JSGlobalContextRef> objectContext(Adopt,
         instance ? jscClassCreateContextWithJSWrapper(objectClass, instance) : JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(context->priv->vm.get()), nullptr));
     JSC::ExecState* exec = toJS(objectContext.get());
-    auto* jsObject = exec->vmEntryGlobalObject();
-    jsObject->setGlobalScopeExtension(JSC::JSWithScope::create(exec->vm(), jsObject, jsObject->globalScope(), toJS(JSContextGetGlobalObject(context->priv->jsContext.get()))));
+    JSC::VM& vm = exec->vm();
+    auto* jsObject = vm.vmEntryGlobalObject(exec);
+    jsObject->setGlobalScopeExtension(JSC::JSWithScope::create(vm, jsObject, jsObject->globalScope(), toJS(JSContextGetGlobalObject(context->priv->jsContext.get()))));
     JSValueRef exception = nullptr;
     JSValueRef result = evaluateScriptInContext(objectContext.get(), String::fromUTF8(code, length < 0 ? strlen(code) : length), uri, lineNumber, &exception);
     if (jscContextHandleExceptionIfNeeded(context, exception))
index dff0aee..59ec94c 100644 (file)
@@ -1,3 +1,77 @@
+2018-08-23  Mark Lam  <mark.lam@apple.com>
+
+        Move vmEntryGlobalObject() to VM from CallFrame.
+        https://bugs.webkit.org/show_bug.cgi?id=188900
+        <rdar://problem/43655753>
+
+        Reviewed by Michael Saboff.
+
+        Also introduced CallFrame::isGlobalExec() which makes use of one property of
+        GlobalExecs to identify them i.e. GlobalExecs have null callerFrame and returnPCs.
+        CallFrame::initGlobalExec() ensures this.
+
+        In contrast, normal CallFrames always have a callerFrame (because they must at
+        least be preceded by a VM EntryFrame) and a returnPC (at least return to the
+        VM entry glue).
+
+        * API/APIUtils.h:
+        (handleExceptionIfNeeded):
+        (setException):
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSContextRef.cpp:
+        (JSGlobalContextRetain):
+        (JSGlobalContextRelease):
+        (JSGlobalContextCopyName):
+        (JSGlobalContextSetName):
+        (JSGlobalContextGetRemoteInspectionEnabled):
+        (JSGlobalContextSetRemoteInspectionEnabled):
+        (JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions):
+        (JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions):
+        (JSGlobalContextGetDebuggerRunLoop):
+        (JSGlobalContextSetDebuggerRunLoop):
+        (JSGlobalContextGetAugmentableInspectorController):
+        * API/JSValue.mm:
+        (reportExceptionToInspector):
+        * API/glib/JSCClass.cpp:
+        (jscContextForObject):
+        * API/glib/JSCContext.cpp:
+        (jsc_context_evaluate_in_object):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::pauseIfNeeded):
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::vmEntryGlobalObject const):
+        (JSC::DebuggerCallFrame::evaluateWithScopeExtension):
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::vmEntryGlobalObject): Deleted.
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::scope const):
+        (JSC::ExecState::noCaller):
+        (JSC::ExecState::isGlobalExec const):
+        * interpreter/Interpreter.cpp:
+        (JSC::notifyDebuggerOfUnwinding):
+        (JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):
+        (JSC::Interpreter::debug):
+        * runtime/CallData.cpp:
+        (JSC::profiledCall):
+        * runtime/Completion.cpp:
+        (JSC::evaluate):
+        (JSC::profiledEvaluate):
+        (JSC::evaluateWithScopeExtension):
+        (JSC::loadAndEvaluateModule):
+        (JSC::loadModule):
+        (JSC::linkAndEvaluateModule):
+        (JSC::importModule):
+        * runtime/ConstructData.cpp:
+        (JSC::profiledConstruct):
+        * runtime/Error.cpp:
+        (JSC::getStackTrace):
+        * runtime/VM.cpp:
+        (JSC::VM::throwException):
+        (JSC::VM::vmEntryGlobalObject const):
+        * runtime/VM.h:
+
 2018-08-23  Andy Estes  <aestes@apple.com>
 
         [Apple Pay] Introduce Apple Pay JS v4 on iOS 12 and macOS Mojave
index cc9102f..a3e7ae6 100644 (file)
@@ -718,7 +718,7 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
     // reseting the pause state before executing any breakpoint actions.
     TemporaryPausedState pausedState(*this);
 
-    JSGlobalObject* vmEntryGlobalObject = callFrame->vmEntryGlobalObject(vm);
+    JSGlobalObject* vmEntryGlobalObject = vm.vmEntryGlobalObject(callFrame);
 
     if (didHitBreakpoint) {
         handleBreakpointHit(vmEntryGlobalObject, breakpoint);
index 86afc69..a9f639c 100644 (file)
@@ -118,7 +118,8 @@ JSC::JSGlobalObject* DebuggerCallFrame::vmEntryGlobalObject() const
     ASSERT(isValid());
     if (!isValid())
         return nullptr;
-    return m_validMachineFrame->vmEntryGlobalObject();
+    VM& vm = m_validMachineFrame->vm();
+    return vm.vmEntryGlobalObject(m_validMachineFrame);
 }
 
 SourceID DebuggerCallFrame::sourceID() const
@@ -252,7 +253,7 @@ JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSOb
         return jsUndefined();
     }
 
-    JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(callFrame);
     if (scopeExtensionObject) {
         JSScope* ignoredPreviousScope = globalObject->globalScope();
         globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, ignoredPreviousScope, scopeExtensionObject));
index 6325dc2..c526577 100644 (file)
@@ -45,6 +45,7 @@ void ExecState::initGlobalExec(ExecState* globalExec, JSCallee* globalCallee)
     globalExec->setReturnPC(0);
     globalExec->setArgumentCountIncludingThis(0);
     globalExec->setCallee(globalCallee);
+    ASSERT(globalExec->isGlobalExec());
 }
 
 bool CallFrame::callSiteBitsAreBytecodeOffset() const
@@ -187,34 +188,6 @@ Register* CallFrame::topOfFrameInternal()
     return registers() + codeBlock->stackPointerOffset();
 }
 
-JSGlobalObject* CallFrame::vmEntryGlobalObject()
-{
-    RELEASE_ASSERT(callee().isCell());
-    if (callee().asCell()->isObject()) { 
-        if (this == lexicalGlobalObject()->globalExec())
-            return lexicalGlobalObject();
-    }
-    // If we're not an object, we're wasm, and therefore we're executing code and the below is safe.
-
-    // For any ExecState that's not a globalExec, the 
-    // dynamic global object must be set since code is running
-    ASSERT(vm().entryScope);
-    return vm().entryScope->globalObject();
-}
-
-JSGlobalObject* CallFrame::vmEntryGlobalObject(VM& vm)
-{
-    if (callee().isCell() && callee().asCell()->isObject()) {
-        if (this == lexicalGlobalObject()->globalExec())
-            return lexicalGlobalObject();
-    }
-
-    // For any ExecState that's not a globalExec, the 
-    // dynamic global object must be set since code is running
-    ASSERT(vm.entryScope);
-    return vm.entryScope->globalObject();
-}
-
 JSGlobalObject* CallFrame::wasmAwareLexicalGlobalObject(VM& vm)
 {
 #if ENABLE(WEBASSEMBLY)
index 6d5d723..1b7c9e3 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-2018 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
@@ -115,18 +115,13 @@ namespace JSC  {
             ASSERT(this[scopeRegisterOffset].Register::scope());
             return this[scopeRegisterOffset].Register::scope();
         }
-        // Global object in which execution began.
-        // This variant is not safe to call from a Wasm frame.
-        JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject();
-        // This variant is safe to call from a Wasm frame.
-        JSGlobalObject* vmEntryGlobalObject(VM&);
 
         JSGlobalObject* wasmAwareLexicalGlobalObject(VM&);
 
         bool isAnyWasmCallee();
 
         // Global object in which the currently executing code was defined.
-        // Differs from vmEntryGlobalObject() during function calls across web browser frames.
+        // Differs from VM::vmEntryGlobalObject() during function calls across web browser frames.
         JSGlobalObject* lexicalGlobalObject() const;
 
         // Differs from lexicalGlobalObject because this will have DOM window shell rather than
@@ -255,7 +250,11 @@ namespace JSC  {
 
         static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + CallFrameSlot::thisArgument - 1; }
 
-        static CallFrame* noCaller() { return 0; }
+        static CallFrame* noCaller() { return nullptr; }
+        bool isGlobalExec() const
+        {
+            return callerFrameAndPC().callerFrame == noCaller() && callerFrameAndPC().pc == nullptr;
+        }
 
         void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[CallFrameSlot::argumentCount].payload() = count; }
         void setCallee(JSObject* callee) { static_cast<Register*>(this)[CallFrameSlot::callee] = callee; }
index e8e0b50..aac401e 100644 (file)
@@ -635,7 +635,7 @@ private:
 ALWAYS_INLINE static void notifyDebuggerOfUnwinding(VM& vm, CallFrame* callFrame)
 {
     auto catchScope = DECLARE_CATCH_SCOPE(vm);
-    if (Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger()) {
+    if (Debugger* debugger = vm.vmEntryGlobalObject(callFrame)->debugger()) {
         SuspendExceptionScope scope(&vm);
         if (callFrame->isAnyWasmCallee()
             || (callFrame->callee().isCell() && callFrame->callee().asCell()->inherits<JSFunction>(vm)))
@@ -754,7 +754,7 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exc
 
 void Interpreter::notifyDebuggerOfExceptionToBeThrown(VM& vm, CallFrame* callFrame, Exception* exception)
 {
-    Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger();
+    Debugger* debugger = vm.vmEntryGlobalObject(callFrame)->debugger();
     if (debugger && debugger->needsExceptionCallbacks() && !exception->didNotifyInspectorOfThrow()) {
         // This code assumes that if the debugger is enabled then there is no inlining.
         // If that assumption turns out to be false then we'll ignore the inlined call
@@ -1327,7 +1327,7 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookType debugHo
 {
     VM& vm = callFrame->vm();
     auto scope = DECLARE_CATCH_SCOPE(vm);
-    Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
+    Debugger* debugger = vm.vmEntryGlobalObject(callFrame)->debugger();
     if (!debugger)
         return;
 
index 226249e..3fe6c37 100644 (file)
@@ -57,13 +57,15 @@ JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const C
 
 JSValue profiledCall(ExecState* exec, ProfilingReason reason, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
 {
-    ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason);
+    VM& vm = exec->vm();
+    ScriptProfilingScope profilingScope(vm.vmEntryGlobalObject(exec), reason);
     return call(exec, functionObject, callType, callData, thisValue, args);
 }
 
 JSValue profiledCall(ExecState* exec, ProfilingReason reason, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, NakedPtr<Exception>& returnedException)
 {
-    ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason);
+    VM& vm = exec->vm();
+    ScriptProfilingScope profilingScope(vm.vmEntryGlobalObject(exec), reason);
     return call(exec, functionObject, callType, callData, thisValue, args, returnedException);
 }
 
index 05fa318..a5fa745 100644 (file)
@@ -98,7 +98,7 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, N
     CodeProfiling profile(source);
 
     if (!thisValue || thisValue.isUndefinedOrNull())
-        thisValue = exec->vmEntryGlobalObject();
+        thisValue = vm.vmEntryGlobalObject(exec);
     JSObject* thisObj = jsCast<JSObject*>(thisValue.toThis(exec, NotStrictMode));
     JSValue result = vm.interpreter->executeProgram(source, exec, thisObj);
 
@@ -114,13 +114,15 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, N
 
 JSValue profiledEvaluate(ExecState* exec, ProfilingReason reason, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException)
 {
-    ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason);
+    VM& vm = exec->vm();
+    ScriptProfilingScope profilingScope(vm.vmEntryGlobalObject(exec), reason);
     return evaluate(exec, source, thisValue, returnedException);
 }
 
 JSValue evaluateWithScopeExtension(ExecState* exec, const SourceCode& source, JSObject* scopeExtensionObject, NakedPtr<Exception>& returnedException)
 {
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
 
     if (scopeExtensionObject) {
         JSScope* ignoredPreviousScope = globalObject->globalScope();
@@ -161,7 +163,7 @@ JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const String& moduleNa
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
 
-    return exec->vmEntryGlobalObject()->moduleLoader()->loadAndEvaluateModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
+    return vm.vmEntryGlobalObject(exec)->moduleLoader()->loadAndEvaluateModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
 }
 
 JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const SourceCode& source, JSValue scriptFetcher)
@@ -174,7 +176,7 @@ JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const SourceCode& sour
 
     Symbol* key = createSymbolForEntryPointModule(vm);
 
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
 
     // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
     globalObject->moduleLoader()->provideFetch(exec, key, source);
@@ -190,7 +192,7 @@ JSInternalPromise* loadModule(ExecState* exec, const String& moduleName, JSValue
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
 
-    return exec->vmEntryGlobalObject()->moduleLoader()->loadModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
+    return vm.vmEntryGlobalObject(exec)->moduleLoader()->loadModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
 }
 
 JSInternalPromise* loadModule(ExecState* exec, const SourceCode& source, JSValue scriptFetcher)
@@ -203,7 +205,7 @@ JSInternalPromise* loadModule(ExecState* exec, const SourceCode& source, JSValue
 
     Symbol* key = createSymbolForEntryPointModule(vm);
 
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
 
     // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
     // FIXME: Introduce JSSourceCode object to wrap around this source.
@@ -220,7 +222,7 @@ JSValue linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey, JSVa
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
 
-    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
     return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(vm, moduleKey), scriptFetcher);
 }
 
@@ -231,7 +233,7 @@ JSInternalPromise* importModule(ExecState* exec, const Identifier& moduleKey, JS
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
 
-    return exec->vmEntryGlobalObject()->moduleLoader()->requestImportModule(exec, moduleKey, parameters, scriptFetcher);
+    return vm.vmEntryGlobalObject(exec)->moduleLoader()->requestImportModule(exec, moduleKey, parameters, scriptFetcher);
 }
 
 } // namespace JSC
index e35da35..3aebbd0 100644 (file)
@@ -58,7 +58,8 @@ JSObject* construct(ExecState* exec, JSValue constructorObject, ConstructType co
 
 JSObject* profiledConstruct(ExecState* exec, ProfilingReason reason, JSValue constructorObject, ConstructType constructType, const ConstructData& constructData, const ArgList& args, JSValue newTarget)
 {
-    ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason);
+    VM& vm = exec->vm();
+    ScriptProfilingScope profilingScope(vm.vmEntryGlobalObject(exec), reason);
     return construct(exec, constructorObject, constructType, constructData, args, newTarget);
 }
 
index 89cd2db..6388e4e 100644 (file)
@@ -169,7 +169,7 @@ std::unique_ptr<Vector<StackFrame>> getStackTrace(ExecState* exec, VM& vm, JSObj
     std::unique_ptr<Vector<StackFrame>> stackTrace = std::make_unique<Vector<StackFrame>>();
     vm.interpreter->getStackTrace(obj, *stackTrace, framesToSkip, errorConstructor->stackTraceLimit().value());
     if (!stackTrace->isEmpty())
-        ASSERT_UNUSED(exec, exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+        ASSERT_UNUSED(exec, exec == vm.topCallFrame || exec->isGlobalExec());
     return stackTrace;
 }
 
index f10ffdb..6f00520 100644 (file)
@@ -832,7 +832,7 @@ void VM::throwException(ExecState* exec, Exception* exception)
         CRASH();
     }
 
-    ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+    ASSERT(exec == topCallFrame || exec->isGlobalExec());
 
     interpreter->notifyDebuggerOfExceptionToBeThrown(*this, exec, exception);
 
@@ -1263,4 +1263,15 @@ void VM::clearScratchBuffers()
         scratchBuffer->setActiveLength(0);
 }
 
+JSGlobalObject* VM::vmEntryGlobalObject(const CallFrame* callFrame) const
+{
+    if (callFrame && callFrame->isGlobalExec()) {
+        ASSERT(callFrame->callee().isCell() && callFrame->callee().asCell()->isObject());
+        ASSERT(callFrame == callFrame->lexicalGlobalObject()->globalExec());
+        return callFrame->lexicalGlobalObject();
+    }
+    ASSERT(entryScope);
+    return entryScope->globalObject();
+}
+
 } // namespace JSC
index f1b9101..c5bc9dd 100644 (file)
@@ -172,6 +172,8 @@ struct HashTable;
 struct Instruction;
 struct ValueProfile;
 
+typedef ExecState CallFrame;
+
 struct LocalTimeOffsetCache {
     LocalTimeOffsetCache()
         : start(0.0)
@@ -293,6 +295,9 @@ public:
     unsigned id() const { return m_id; }
     bool isEntered() const { return !!entryScope; }
 
+    // Global object in which execution began.
+    JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject(const CallFrame*) const;
+
 private:
     unsigned nextID();
 
index 2bc2e2f..e8599f3 100644 (file)
@@ -1,3 +1,33 @@
+2018-08-23  Mark Lam  <mark.lam@apple.com>
+
+        Move vmEntryGlobalObject() to VM from CallFrame.
+        https://bugs.webkit.org/show_bug.cgi?id=188900
+        <rdar://problem/43655753>
+
+        Reviewed by Michael Saboff.
+
+        No new tests needed because this patch does not introduce new functionality.
+
+        * bindings/js/JSCustomXPathNSResolver.cpp:
+        (WebCore::JSCustomXPathNSResolver::create):
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::callerGlobalObject):
+        (WebCore::toJSDOMGlobalObject): Deleted.
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::firstDOMWindow):
+        * bridge/c/c_utility.cpp:
+        (JSC::Bindings::convertValueToNPVariant):
+        * bridge/objc/WebScriptObject.mm:
+        (WebCore::addExceptionToConsole):
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::moveGlobalExceptionToExecState):
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::convertValueToObjcObject):
+        * bridge/objc/objc_utility.mm:
+        (JSC::Bindings::convertValueToObjcValue):
+        * testing/Internals.cpp:
+        (WebCore::Internals::cloneArrayBuffer):
+
 2018-08-23  Andy Estes  <aestes@apple.com>
 
         [Apple Pay] Introduce Apple Pay JS v4 on iOS 12 and macOS Mojave
index 21acf02..ae2c2db 100644 (file)
@@ -51,7 +51,8 @@ ExceptionOr<Ref<JSCustomXPathNSResolver>> JSCustomXPathNSResolver::create(ExecSt
     if (!resolverObject)
         return Exception { TypeMismatchError };
 
-    return adoptRef(*new JSCustomXPathNSResolver(state.vm(), resolverObject, asJSDOMWindow(state.vmEntryGlobalObject())));
+    VM& vm = state.vm();
+    return adoptRef(*new JSCustomXPathNSResolver(vm, resolverObject, asJSDOMWindow(vm.vmEntryGlobalObject(&state))));
 }
 
 JSCustomXPathNSResolver::JSCustomXPathNSResolver(VM& vm, JSObject* customResolver, JSDOMWindow* globalObject)
index c157dbb..fa8500e 100644 (file)
@@ -304,7 +304,11 @@ JSDOMGlobalObject& callerGlobalObject(ExecState& state)
 
     GetCallerGlobalObjectFunctor iter;
     state.iterate(iter);
-    return *jsCast<JSDOMGlobalObject*>(iter.globalObject() ? iter.globalObject() : state.vmEntryGlobalObject());
+    if (iter.globalObject())
+        return *jsCast<JSDOMGlobalObject*>(iter.globalObject());
+
+    VM& vm = state.vm();
+    return *jsCast<JSDOMGlobalObject*>(vm.vmEntryGlobalObject(&state));
 }
 
 JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext& context, DOMWrapperWorld& world)
index 6764fc2..a3ed0e2 100644 (file)
@@ -269,7 +269,8 @@ DOMWindow& activeDOMWindow(ExecState& state)
 
 DOMWindow& firstDOMWindow(ExecState& state)
 {
-    return asJSDOMWindow(state.vmEntryGlobalObject())->wrapped();
+    VM& vm = state.vm();
+    return asJSDOMWindow(vm.vmEntryGlobalObject(&state))->wrapped();
 }
 
 Document* responsibleDocument(ExecState& state)
index 4365855..42f41f3 100644 (file)
@@ -96,7 +96,7 @@ void convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result)
                 OBJECT_TO_NPVARIANT(obj, *result);
             }
         } else {
-            JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+            JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
 
             RootObject* rootObject = findRootObject(globalObject);
             if (rootObject) {
index 97c7d7c..02b8428 100644 (file)
@@ -122,7 +122,8 @@ id createJSWrapper(JSC::JSObject* object, RefPtr<JSC::Bindings::RootObject>&& or
 
 static void addExceptionToConsole(ExecState* exec, JSC::Exception* exception)
 {
-    JSDOMWindow* window = asJSDOMWindow(exec->vmEntryGlobalObject());
+    JSC::VM& vm = exec->vm();
+    JSDOMWindow* window = asJSDOMWindow(vm.vmEntryGlobalObject(exec));
     if (!window || !exception)
         return;
     reportException(exec, exception);
index b81068a..0aec0ce 100644 (file)
@@ -88,8 +88,8 @@ void ObjcInstance::moveGlobalExceptionToExecState(ExecState* exec)
         return;
     }
 
-    if (!s_exceptionEnvironment || s_exceptionEnvironment == exec->vmEntryGlobalObject()) {
-        JSLockHolder lock(exec);
+    if (!s_exceptionEnvironment || s_exceptionEnvironment == vm.vmEntryGlobalObject(exec)) {
+        JSLockHolder lock(vm);
         throwError(exec, scope, s_exception);
     }
 
index 29c58c5..e08b048 100644 (file)
@@ -122,7 +122,8 @@ JSValue ObjcField::valueFromInstance(ExecState* exec, const Instance* instance)
 
 static id convertValueToObjcObject(ExecState* exec, JSValue value)
 {
-    RefPtr<RootObject> rootObject = findRootObject(exec->vmEntryGlobalObject());
+    VM& vm = exec->vm();
+    RefPtr<RootObject> rootObject = findRootObject(vm.vmEntryGlobalObject(exec));
     if (!rootObject)
         return nil;
     return [webScriptObjectClass() _convertValueToObjcValue:value originRootObject:rootObject.get() rootObject:rootObject.get()];
index 01cbf62..a4354bb 100644 (file)
@@ -88,9 +88,10 @@ ObjcValue convertValueToObjcValue(ExecState* exec, JSValue value, ObjcValueType
 
     switch (type) {
         case ObjcObjectType: {
-            JSLockHolder lock(exec);
+            VM& vm = exec->vm();
+            JSLockHolder lock(vm);
             
-            JSGlobalObject *originGlobalObject = exec->vmEntryGlobalObject();
+            JSGlobalObject *originGlobalObject = vm.vmEntryGlobalObject(exec);
             RootObject* originRootObject = findRootObject(originGlobalObject);
 
             JSGlobalObject* globalObject = 0;
index 9ba1d27..c600b35 100644 (file)
@@ -4122,7 +4122,7 @@ bool Internals::isReadableStreamDisturbed(JSC::ExecState& state, JSValue stream)
 JSValue Internals::cloneArrayBuffer(JSC::ExecState& state, JSValue buffer, JSValue srcByteOffset, JSValue srcLength)
 {
     JSC::VM& vm = state.vm();
-    JSGlobalObject* globalObject = state.vmEntryGlobalObject();
+    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(&state);
     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData);
     const Identifier& privateName = clientData->builtinNames().cloneArrayBufferPrivateName();
     JSValue value;
index faf825e..dee686d 100644 (file)
@@ -1,3 +1,14 @@
+2018-08-23  Mark Lam  <mark.lam@apple.com>
+
+        Move vmEntryGlobalObject() to VM from CallFrame.
+        https://bugs.webkit.org/show_bug.cgi?id=188900
+        <rdar://problem/43655753>
+
+        Reviewed by Michael Saboff.
+
+        * WebView/WebScriptDebugger.mm:
+        (WebScriptDebugger::sourceParsed):
+
 2018-08-23  Andy Estes  <aestes@apple.com>
 
         [Apple Pay] Introduce Apple Pay JS v4 on iOS 12 and macOS Mojave
index 17c1afa..1addd91 100644 (file)
@@ -93,7 +93,8 @@ void WebScriptDebugger::sourceParsed(ExecState* exec, SourceProvider* sourceProv
     NSURL *nsURL = toNSURL(sourceProvider->url());
     int firstLine = sourceProvider->startPosition().m_line.oneBasedInt();
 
-    WebFrame *webFrame = toWebFrame(exec->vmEntryGlobalObject());
+    VM& vm = exec->vm();
+    WebFrame *webFrame = toWebFrame(vm.vmEntryGlobalObject(exec));
     WebView *webView = [webFrame webView];
     WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView);