Ignore:
Timestamp:
Aug 20, 2015, 9:59:59 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] prototyping module loader in JSC shell
https://bugs.webkit.org/show_bug.cgi?id=147876

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch implements ES6 Module Loader part. The implementation is based on
the latest draft[1, 2]. The naive implementation poses several problems.
This patch attempts to solve the spec issues and proposes the fix[3, 4, 5].

We construct the JSC internal module loader based on the ES6 Promises.
The chain of the promises represents the dependency graph of the modules and
it automatically enables asynchronous module fetching.
To leverage the Promises internally, we use the InternalPromise landed in r188681.

The loader has several platform-dependent hooks. The platform can implement
these hooks to provide the functionality missing in the module loaders, like
"how to fetch the resources". The method table of the JSGlobalObject is extended
to accept these hooks from the platform.

This patch focus on the loading part. So we don't create the module environment
and don't link the modules yet.

To test the current module progress easily, we add the -m option to the JSC shell.
When this option is specified, we load the given script as the module. And to use
the module loading inside the JSC shell, we added the simple loader hook for fetching.
It fetches the module content from the file system.

And to use the ES6 Map in the Loader implementation, we added @get and @set methods to the Map.
But it conflicts with the existing getPrivateName method. Rename it to lookUpPrivateName.

[1]: https://whatwg.github.io/loader/
[2]: https://github.com/whatwg/loader/commit/214c7a6625b445bdf411c39984f36f01139a24be
[3]: https://github.com/whatwg/loader/pull/66
[4]: https://github.com/whatwg/loader/pull/67
[5]: https://github.com/whatwg/loader/issues/68
[6]: https://bugs.webkit.org/show_bug.cgi?id=148136

(JSC::BuiltinNames::lookUpPrivateName):
(JSC::BuiltinNames::lookUpPublicName):
(JSC::BuiltinNames::getPrivateName): Deleted.
(JSC::BuiltinNames::getPublicName): Deleted.

  • builtins/ModuleLoaderObject.js: Added.

(setStateToMax):
(newRegistryEntry):
(forceFulfillPromise):
(fulfillFetch):
(fulfillTranslate):
(fulfillInstantiate):
(instantiation):
(requestFetch):
(requestTranslate):
(requestInstantiate):
(requestResolveDependencies.resolveDependenciesPromise.this.requestInstantiate.then.):
(requestResolveDependencies.resolveDependenciesPromise.this.requestInstantiate.then):
(requestResolveDependencies):
(requestInstantiateAll):
(provide):

  • jsc.cpp:

(stringFromUTF):
(jscSource):
(GlobalObject::moduleLoaderFetch):
(functionCheckModuleSyntax):
(dumpException):
(runWithScripts):
(printUsageStatement):
(CommandLine::parseArguments):
(jscmain):
(CommandLine::CommandLine): Deleted.

  • parser/Lexer.cpp:

(JSC::Lexer<LChar>::parseIdentifier):
(JSC::Lexer<UChar>::parseIdentifier):

  • parser/ModuleAnalyzer.cpp:

(JSC::ModuleAnalyzer::ModuleAnalyzer):
(JSC::ModuleAnalyzer::exportVariable):
(JSC::ModuleAnalyzer::analyze):

  • parser/ModuleAnalyzer.h:

(JSC::ModuleAnalyzer::moduleRecord):

  • parser/ModuleRecord.cpp:

(JSC::printableName): Deleted.
(JSC::ModuleRecord::dump): Deleted.

  • parser/ModuleRecord.h:

(JSC::ModuleRecord::ImportEntry::isNamespace): Deleted.
(JSC::ModuleRecord::create): Deleted.
(JSC::ModuleRecord::appendRequestedModule): Deleted.
(JSC::ModuleRecord::addImportEntry): Deleted.
(JSC::ModuleRecord::addExportEntry): Deleted.
(JSC::ModuleRecord::addStarExportEntry): Deleted.

  • parser/Nodes.h:
  • parser/NodesAnalyzeModule.cpp:

(JSC::ImportDeclarationNode::analyzeModule):
(JSC::ExportAllDeclarationNode::analyzeModule):
(JSC::ExportNamedDeclarationNode::analyzeModule):

  • runtime/CommonIdentifiers.cpp:

(JSC::CommonIdentifiers::lookUpPrivateName):
(JSC::CommonIdentifiers::lookUpPublicName):
(JSC::CommonIdentifiers::getPrivateName): Deleted.
(JSC::CommonIdentifiers::getPublicName): Deleted.

  • runtime/CommonIdentifiers.h:
  • runtime/Completion.cpp:

(JSC::checkModuleSyntax):
(JSC::evaluateModule):

  • runtime/Completion.h:
  • runtime/ExceptionHelpers.cpp:

(JSC::createUndefinedVariableError):

  • runtime/Identifier.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::moduleLoader):
(JSC::JSGlobalObject::moduleRecordStructure):

  • runtime/JSModuleRecord.cpp: Renamed from Source/JavaScriptCore/parser/ModuleRecord.cpp.

(JSC::JSModuleRecord::destroy):
(JSC::JSModuleRecord::finishCreation):
(JSC::printableName):
(JSC::JSModuleRecord::dump):

  • runtime/JSModuleRecord.h: Renamed from Source/JavaScriptCore/parser/ModuleRecord.h.

(JSC::JSModuleRecord::ImportEntry::isNamespace):
(JSC::JSModuleRecord::createStructure):
(JSC::JSModuleRecord::create):
(JSC::JSModuleRecord::requestedModules):
(JSC::JSModuleRecord::JSModuleRecord):
(JSC::JSModuleRecord::appendRequestedModule):
(JSC::JSModuleRecord::addImportEntry):
(JSC::JSModuleRecord::addExportEntry):
(JSC::JSModuleRecord::addStarExportEntry):

  • runtime/MapPrototype.cpp:

(JSC::MapPrototype::finishCreation):

  • runtime/ModuleLoaderObject.cpp: Added.

(JSC::ModuleLoaderObject::ModuleLoaderObject):
(JSC::ModuleLoaderObject::finishCreation):
(JSC::ModuleLoaderObject::getOwnPropertySlot):
(JSC::printableModuleKey):
(JSC::ModuleLoaderObject::provide):
(JSC::ModuleLoaderObject::requestInstantiateAll):
(JSC::ModuleLoaderObject::resolve):
(JSC::ModuleLoaderObject::fetch):
(JSC::ModuleLoaderObject::translate):
(JSC::ModuleLoaderObject::instantiate):
(JSC::moduleLoaderObjectParseModule):
(JSC::moduleLoaderObjectRequestedModules):
(JSC::moduleLoaderObjectResolve):
(JSC::moduleLoaderObjectFetch):
(JSC::moduleLoaderObjectTranslate):
(JSC::moduleLoaderObjectInstantiate):

  • runtime/ModuleLoaderObject.h: Added.

(JSC::ModuleLoaderObject::create):
(JSC::ModuleLoaderObject::createStructure):

  • runtime/Options.h:

Source/WebCore:

Just fill Loader hooks with nullptr.

  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSWorkerGlobalScopeBase.cpp:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Completion.cpp

    r188417 r188752  
    2929#include "Exception.h"
    3030#include "Interpreter.h"
     31#include "JSCInlines.h"
    3132#include "JSGlobalObject.h"
    3233#include "JSLock.h"
    33 #include "JSCInlines.h"
     34#include "JSModuleRecord.h"
    3435#include "ModuleAnalyzer.h"
    35 #include "ModuleRecord.h"
     36#include "ModuleLoaderObject.h"
    3637#include "Parser.h"
    3738#include <wtf/WTFThreadData.h>
     
    6465}
    6566
    66 bool checkModuleSyntax(VM& vm, const SourceCode& source, ParserError& error)
     67bool checkModuleSyntax(ExecState* exec, const SourceCode& source, ParserError& error)
    6768{
     69    VM& vm = exec->vm();
    6870    JSLockHolder lock(vm);
    6971    RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
     
    7476        return false;
    7577
    76     ModuleAnalyzer moduleAnalyzer(vm, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables());
     78    PrivateName privateName(PrivateName::Description, "EntryPointModule");
     79    ModuleAnalyzer moduleAnalyzer(exec, Identifier::fromUid(privateName), moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables());
    7780    moduleAnalyzer.analyze(*moduleProgramNode);
    7881    return true;
     
    109112}
    110113
     114void evaluateModule(ExecState* exec, const SourceCode& source, NakedPtr<Exception>& returnedException)
     115{
     116    JSLockHolder lock(exec);
     117    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     118    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     119
     120    CodeProfiling profile(source);
     121
     122    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
     123
     124    // Generate the unique key for the source-provided module.
     125    PrivateName privateName(PrivateName::Description, "EntryPointModule");
     126    Symbol* key = Symbol::create(exec->vm(), *privateName.uid());
     127
     128    ModuleLoaderObject* moduleLoader = globalObject->moduleLoader();
     129
     130    // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
     131    moduleLoader->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.toString());
     132    if (exec->hadException()) {
     133        returnedException = exec->exception();
     134        exec->clearException();
     135        return;
     136    }
     137
     138    // FIXME: Now, we don't implement the linking phase yet.
     139    // So here, we just call requestInstantiateAll to only perform the module loading.
     140    // At last, it should be replaced with requestReady.
     141    // https://bugs.webkit.org/show_bug.cgi?id=148172
     142    moduleLoader->requestInstantiateAll(exec, key);
     143
     144    // FIXME: We should also handle the asynchronous Syntax Errors that will be delivered by the rejected promise.
     145    // https://bugs.webkit.org/show_bug.cgi?id=148173
     146    if (exec->hadException()) {
     147        returnedException = exec->exception();
     148        exec->clearException();
     149        return;
     150    }
     151}
     152
    111153} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.