Removed some unnecessary indirection in code generation
https://bugs.webkit.org/show_bug.cgi?id=165264

Reviewed by Keith Miller.

There's no need to route through JSGlobalObject when producing code --
it just made the code harder to read.

This patch moves functions from JSGlobalObject to their singleton
call sites.

* runtime/CodeCache.cpp:
(JSC::CodeCache::getUnlinkedEvalCodeBlock):
(JSC::CodeCache::getUnlinkedGlobalEvalCodeBlock): Deleted.
* runtime/CodeCache.h:
* runtime/DirectEvalExecutable.cpp:
(JSC::DirectEvalExecutable::create):
* runtime/IndirectEvalExecutable.cpp:
(JSC::IndirectEvalExecutable::create):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::createProgramCodeBlock): Deleted.
(JSC::JSGlobalObject::createLocalEvalCodeBlock): Deleted.
(JSC::JSGlobalObject::createGlobalEvalCodeBlock): Deleted.
(JSC::JSGlobalObject::createModuleProgramCodeBlock): Deleted.
* runtime/JSGlobalObject.h:
* runtime/ModuleProgramExecutable.cpp:
(JSC::ModuleProgramExecutable::create):
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::initializeGlobalProperties):
* runtime/ProgramExecutable.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@209196 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index f0b6c75..e04583b 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,36 @@
+2016-12-01  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed some unnecessary indirection in code generation
+        https://bugs.webkit.org/show_bug.cgi?id=165264
+
+        Reviewed by Keith Miller.
+
+        There's no need to route through JSGlobalObject when producing code --
+        it just made the code harder to read.
+
+        This patch moves functions from JSGlobalObject to their singleton
+        call sites.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getUnlinkedEvalCodeBlock):
+        (JSC::CodeCache::getUnlinkedGlobalEvalCodeBlock): Deleted.
+        * runtime/CodeCache.h:
+        * runtime/DirectEvalExecutable.cpp:
+        (JSC::DirectEvalExecutable::create):
+        * runtime/IndirectEvalExecutable.cpp:
+        (JSC::IndirectEvalExecutable::create):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::createProgramCodeBlock): Deleted.
+        (JSC::JSGlobalObject::createLocalEvalCodeBlock): Deleted.
+        (JSC::JSGlobalObject::createGlobalEvalCodeBlock): Deleted.
+        (JSC::JSGlobalObject::createModuleProgramCodeBlock): Deleted.
+        * runtime/JSGlobalObject.h:
+        * runtime/ModuleProgramExecutable.cpp:
+        (JSC::ModuleProgramExecutable::create):
+        * runtime/ProgramExecutable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/ProgramExecutable.h:
+
 2016-11-30  JF Bastien  <jfbastien@apple.com>
 
         WebAssembly: update binary format to 0xD version
diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp
index 46f7aa3..2d1d675 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.cpp
+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp
@@ -85,7 +85,7 @@
     return getUnlinkedGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, debuggerMode, error, EvalContextType::None);
 }
 
-UnlinkedEvalCodeBlock* CodeCache::getUnlinkedGlobalEvalCodeBlock(VM& vm, IndirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType)
+UnlinkedEvalCodeBlock* CodeCache::getUnlinkedEvalCodeBlock(VM& vm, IndirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType)
 {
     return getUnlinkedGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType);
 }
diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h
index adeb33b..676e12e 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.h
+++ b/Source/JavaScriptCore/runtime/CodeCache.h
@@ -194,7 +194,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     UnlinkedProgramCodeBlock* getUnlinkedProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictMode, DebuggerMode, ParserError&);
-    UnlinkedEvalCodeBlock* getUnlinkedGlobalEvalCodeBlock(VM&, IndirectEvalExecutable*, const SourceCode&, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType);
+    UnlinkedEvalCodeBlock* getUnlinkedEvalCodeBlock(VM&, IndirectEvalExecutable*, const SourceCode&, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType);
     UnlinkedModuleProgramCodeBlock* getUnlinkedModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, DebuggerMode, ParserError&);
     UnlinkedFunctionExecutable* getUnlinkedGlobalFunctionExecutable(VM&, const Identifier&, const SourceCode&, DebuggerMode, ParserError&);
 
diff --git a/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp b/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp
index fc4e4cf..47d3657 100644
--- a/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp
+++ b/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp
@@ -26,9 +26,12 @@
 #include "config.h"
 #include "DirectEvalExecutable.h"
 
+#include "CodeCache.h"
+#include "Debugger.h"
 #include "Error.h"
 #include "HeapInlines.h"
 #include "JSCJSValueInlines.h"
+#include "ParserError.h"
 
 namespace JSC {
 
@@ -46,10 +49,21 @@
     auto* executable = new (NotNull, allocateCell<DirectEvalExecutable>(*exec->heap())) DirectEvalExecutable(exec, source, isInStrictContext, derivedContextType, isArrowFunctionContext, evalContextType);
     executable->finishCreation(vm);
 
-    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createLocalEvalCodeBlock(exec, executable, variablesUnderTDZ);
-    ASSERT(!!scope.exception() == !unlinkedEvalCode);
-    if (!unlinkedEvalCode)
-        return 0;
+    ParserError error;
+    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
+    DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
+
+    // We don't bother with CodeCache here because direct eval uses a specialized EvalCodeCache.
+    UnlinkedEvalCodeBlock* unlinkedEvalCode = generateUnlinkedCodeBlock<UnlinkedEvalCodeBlock>(
+        vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType, variablesUnderTDZ);
+
+    if (globalObject->hasDebugger())
+        globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message());
+
+    if (error.isValid()) {
+        throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source()));
+        return nullptr;
+    }
 
     executable->m_unlinkedEvalCodeBlock.set(vm, executable, unlinkedEvalCode);
 
diff --git a/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp b/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp
index a75e908..db9269e 100644
--- a/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp
+++ b/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp
@@ -26,9 +26,12 @@
 #include "config.h"
 #include "IndirectEvalExecutable.h"
 
+#include "CodeCache.h"
+#include "Debugger.h"
 #include "Error.h"
 #include "HeapInlines.h"
 #include "JSCJSValueInlines.h"
+#include "ParserError.h"
 
 namespace JSC {
 
@@ -46,10 +49,20 @@
     auto* executable = new (NotNull, allocateCell<IndirectEvalExecutable>(*exec->heap())) IndirectEvalExecutable(exec, source, isInStrictContext, derivedContextType, isArrowFunctionContext, evalContextType);
     executable->finishCreation(vm);
 
-    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createGlobalEvalCodeBlock(exec, executable);
-    ASSERT(!!scope.exception() == !unlinkedEvalCode);
-    if (!unlinkedEvalCode)
-        return 0;
+    ParserError error;
+    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
+    DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
+    
+    UnlinkedEvalCodeBlock* unlinkedEvalCode = vm.codeCache()->getUnlinkedEvalCodeBlock(
+        vm, executable, executable->source(), strictMode, debuggerMode, error, evalContextType);
+
+    if (globalObject->hasDebugger())
+        globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message());
+
+    if (error.isValid()) {
+        throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source()));
+        return nullptr;
+    }
 
     executable->m_unlinkedEvalCodeBlock.set(vm, executable, unlinkedEvalCode);
 
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index a4cd428..4b97705 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -1332,96 +1332,6 @@
     ASSERT_GC_OBJECT_INHERITS(globalObject, JSGlobalObject::info());
 }
 
-UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* callFrame, ProgramExecutable* executable, JSObject** exception)
-{
-    ParserError error;
-    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
-    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
-    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getUnlinkedProgramCodeBlock(
-        vm(), executable, executable->source(), strictMode, 
-        debuggerMode, error);
-
-    if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
-
-    if (error.isValid()) {
-        *exception = error.toErrorObject(this, executable->source());
-        return nullptr;
-    }
-    
-    return unlinkedCodeBlock;
-}
-
-UnlinkedEvalCodeBlock* JSGlobalObject::createLocalEvalCodeBlock(CallFrame* callFrame, DirectEvalExecutable* executable, const VariableEnvironment* variablesUnderTDZ)
-{
-    VM& vm = this->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    ParserError error;
-    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
-    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
-    EvalContextType evalContextType = executable->executableInfo().evalContextType();
-
-    // We don't bother with CodeCache here because local eval uses a specialized EvalCodeCache.
-    UnlinkedEvalCodeBlock* unlinkedCodeBlock = generateUnlinkedCodeBlock<UnlinkedEvalCodeBlock>(
-        vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType, variablesUnderTDZ);
-
-    if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
-
-    if (error.isValid()) {
-        throwVMError(callFrame, scope, error.toErrorObject(this, executable->source()));
-        return nullptr;
-    }
-
-    return unlinkedCodeBlock;
-}
-
-UnlinkedEvalCodeBlock* JSGlobalObject::createGlobalEvalCodeBlock(CallFrame* callFrame, IndirectEvalExecutable* executable)
-{
-    VM& vm = this->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    ParserError error;
-    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
-    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
-    EvalContextType evalContextType = executable->executableInfo().evalContextType();
-    
-    UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm.codeCache()->getUnlinkedGlobalEvalCodeBlock(
-        vm, executable, executable->source(), strictMode, debuggerMode, error, evalContextType);
-
-    if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
-
-    if (error.isValid()) {
-        throwVMError(callFrame, scope, error.toErrorObject(this, executable->source()));
-        return nullptr;
-    }
-
-    return unlinkedCodeBlock;
-}
-
-UnlinkedModuleProgramCodeBlock* JSGlobalObject::createModuleProgramCodeBlock(CallFrame* callFrame, ModuleProgramExecutable* executable)
-{
-    VM& vm = this->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    ParserError error;
-    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
-    UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock = vm.codeCache()->getUnlinkedModuleProgramCodeBlock(
-        vm, executable, executable->source(), debuggerMode, error);
-
-    if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
-
-    if (error.isValid()) {
-        throwVMError(callFrame, scope, error.toErrorObject(this, executable->source()));
-        return nullptr;
-    }
-
-    return unlinkedCodeBlock;
-}
-
 void JSGlobalObject::setRemoteDebuggingEnabled(bool enabled)
 {
 #if ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 71d9802..505190b 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -834,11 +834,6 @@
     unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
     WeakRandom& weakRandom() { return m_weakRandom; }
 
-    UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
-    UnlinkedEvalCodeBlock* createLocalEvalCodeBlock(CallFrame*, DirectEvalExecutable*, const VariableEnvironment*);
-    UnlinkedEvalCodeBlock* createGlobalEvalCodeBlock(CallFrame*, IndirectEvalExecutable*);
-    UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*);
-
     bool needsSiteSpecificQuirks() const { return m_needsSiteSpecificQuirks; }
 
 protected:
diff --git a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp
index 0b285e8..67d489a 100644
--- a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp
+++ b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp
@@ -27,6 +27,7 @@
 
 #include "BatchedTransitionOptimizer.h"
 #include "CodeBlock.h"
+#include "CodeCache.h"
 #include "Debugger.h"
 #include "JIT.h"
 #include "JSCInlines.h"
@@ -53,13 +54,26 @@
 
 ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source)
 {
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(*exec->heap())) ModuleProgramExecutable(exec, source);
     executable->finishCreation(exec->vm());
 
-    UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = globalObject->createModuleProgramCodeBlock(exec, executable);
-    if (!unlinkedModuleProgramCode)
+    ParserError error;
+    DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
+    UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock(
+        vm, executable, executable->source(), debuggerMode, error);
+
+    if (globalObject->hasDebugger())
+        globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message());
+
+    if (error.isValid()) {
+        throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source()));
         return nullptr;
+    }
+
     executable->m_unlinkedModuleProgramCodeBlock.set(exec->vm(), executable, unlinkedModuleProgramCode);
 
     executable->m_moduleEnvironmentSymbolTable.set(exec->vm(), executable, jsCast<SymbolTable*>(unlinkedModuleProgramCode->constantRegister(unlinkedModuleProgramCode->moduleEnvironmentSymbolTableConstantRegisterOffset()).get())->cloneScopePart(exec->vm()));
diff --git a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp
index 5b8a48d..e46607d 100644
--- a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp
+++ b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp
@@ -27,6 +27,7 @@
 
 #include "BatchedTransitionOptimizer.h"
 #include "CodeBlock.h"
+#include "CodeCache.h"
 #include "Debugger.h"
 #include "Exception.h"
 #include "JIT.h"
@@ -79,6 +80,19 @@
     RELEASE_ASSERT(globalObject);
     ASSERT(&globalObject->vm() == &vm);
 
+    ParserError error;
+    JSParserStrictMode strictMode = isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
+    DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
+
+    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm.codeCache()->getUnlinkedProgramCodeBlock(
+        vm, this, source(), strictMode, debuggerMode, error);
+
+    if (globalObject->hasDebugger())
+        globalObject->debugger()->sourceParsed(callFrame, source().provider(), error.line(), error.message());
+
+    if (error.isValid())
+        return error.toErrorObject(globalObject, source());
+
     JSValue nextPrototype = globalObject->getPrototypeDirect();
     while (nextPrototype && nextPrototype.isObject()) {
         if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType)) {
@@ -88,11 +102,6 @@
         nextPrototype = asObject(nextPrototype)->getPrototypeDirect();
     }
     
-    JSObject* exception = nullptr;
-    UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception);
-    if (UNLIKELY(exception))
-        return exception;
-
     JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment();
     const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
     const VariableEnvironment& lexicalDeclarations = unlinkedCodeBlock->lexicalDeclarations();
diff --git a/Source/JavaScriptCore/runtime/ProgramExecutable.h b/Source/JavaScriptCore/runtime/ProgramExecutable.h
index 3041af5..85ec4b5 100644
--- a/Source/JavaScriptCore/runtime/ProgramExecutable.h
+++ b/Source/JavaScriptCore/runtime/ProgramExecutable.h
@@ -42,7 +42,6 @@
         return executable;
     }
 
-
     JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);
 
     static void destroy(JSCell*);