Diff
Modified: trunk/JSTests/ChangeLog (210521 => 210522)
--- trunk/JSTests/ChangeLog 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/JSTests/ChangeLog 2017-01-09 22:02:47 UTC (rev 210522)
@@ -1,3 +1,31 @@
+2017-01-09 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Prototype dynamic-import
+ https://bugs.webkit.org/show_bug.cgi?id=165724
+
+ Reviewed by Saam Barati.
+
+ * stress/import-basic.js: Added.
+ (async.async.load):
+ (async):
+ (catch):
+ * stress/import-from-eval.js: Added.
+ (async):
+ (catch):
+ * stress/import-syntax.js: Added.
+ (testSyntaxError):
+ * stress/import-tests/cocoa.js: Added.
+ (export.Cocoa):
+ (export.hello):
+ * stress/import-tests/multiple.js: Added.
+ (export.result):
+ * stress/import-tests/multiple2.js: Added.
+ (export.ok):
+ * stress/import-tests/should.js: Added.
+ (export.shouldBe):
+ (export.shouldThrow):
+ * stress/modules-syntax-error.js:
+
2017-01-09 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r210476.
Added: trunk/JSTests/stress/import-basic.js (0 => 210522)
--- trunk/JSTests/stress/import-basic.js (rev 0)
+++ trunk/JSTests/stress/import-basic.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,53 @@
+(async function () {
+ const { shouldBe } = await import('./import-tests/should.js');
+ {
+ let a = await import('./import-tests/cocoa.js');
+ let b = await import('./import-tests/cocoa.js');
+ shouldBe(a, b);
+ shouldBe(a.hello(), 42);
+ }
+
+ {
+ let a = await import('./import-tests/multiple.js');
+ let a2 = await a.result();
+ shouldBe(a !== a2, true);
+ shouldBe(a2.ok(), 42);
+ let a3 = await a.result();
+ shouldBe(a2, a3);
+ }
+
+ {
+ let error = null;
+ try {
+ let a = await import({ toString() { throw new Error('out'); } });
+ } catch (e) {
+ error = e;
+ }
+ shouldBe(error !== null, true);
+ shouldBe(String(error), `Error: out`);
+ }
+
+ {
+ async function load(cond) {
+ if (cond)
+ return import('./import-tests/cocoa.js');
+ return undefined;
+ }
+
+ let v = await load(false);
+ shouldBe(v, undefined);
+ let v2 = await load(true);
+ let v3 = await import('./import-tests/cocoa.js');
+ shouldBe(v2, v2);
+ }
+
+ {
+ let value = './import-tests/cocoa.js';
+ let v = await import(value);
+ let v2 = await import('./import-tests/cocoa.js');
+ shouldBe(v, v2);
+ }
+}()).catch((error) => {
+ print(String(error));
+ abort();
+});
Added: trunk/JSTests/stress/import-from-eval.js (0 => 210522)
--- trunk/JSTests/stress/import-from-eval.js (rev 0)
+++ trunk/JSTests/stress/import-from-eval.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,36 @@
+(async function () {
+ const { shouldBe, shouldThrow } = await import("./import-tests/should.js");
+
+ {
+ let cocoa = await eval(`import("./import-tests/cocoa.js")`);
+ shouldBe(cocoa.hello(), 42);
+ }
+
+ {
+ let cocoa = await (0, eval)(`import("./import-tests/cocoa.js")`);
+ shouldBe(cocoa.hello(), 42);
+ }
+
+ {
+ let cocoa = await eval(`eval('import("./import-tests/cocoa.js")')`);
+ shouldBe(cocoa.hello(), 42);
+ }
+
+ {
+ let cocoa = await ((new Function(`return eval('import("./import-tests/cocoa.js")')`))());
+ shouldBe(cocoa.hello(), 42);
+ }
+
+ {
+ let cocoa = await eval(`(new Function('return import("./import-tests/cocoa.js")'))()`);
+ shouldBe(cocoa.hello(), 42);
+ }
+
+ {
+ let cocoa = await [`import("./import-tests/cocoa.js")`].map(eval)[0];
+ shouldBe(cocoa.hello(), 42);
+ }
+}()).catch((error) => {
+ print(String(error));
+ abort();
+});
Added: trunk/JSTests/stress/import-syntax.js (0 => 210522)
--- trunk/JSTests/stress/import-syntax.js (rev 0)
+++ trunk/JSTests/stress/import-syntax.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,59 @@
+function testSyntaxError(script, message) {
+ var error = null;
+ try {
+ eval(script);
+ } catch (e) {
+ error = e;
+ }
+ if (!error)
+ throw new Error("Expected syntax error not thrown");
+
+ if (String(error) !== message)
+ throw new Error(`Bad error: ${String(error)}`);
+}
+
+async function testSyntax(script, message) {
+ var error = null;
+ try {
+ await eval(script);
+ } catch (e) {
+ error = e;
+ }
+ if (error) {
+ if (error instanceof SyntaxError)
+ throw new Error("Syntax error thrown");
+ }
+}
+
+testSyntaxError(`import)`, `SyntaxError: Unexpected token ')'. import call expects exactly one argument.`);
+testSyntaxError(`new import(`, `SyntaxError: Cannot use new with import.`);
+testSyntaxError(`import.hello()`, `SyntaxError: Unexpected token '.'. import call expects exactly one argument.`);
+testSyntaxError(`import[`, `SyntaxError: Unexpected token '['. import call expects exactly one argument.`);
+testSyntaxError(`import<`, `SyntaxError: Unexpected token '<'. import call expects exactly one argument.`);
+
+testSyntaxError(`import()`, `SyntaxError: Unexpected token ')'`);
+testSyntaxError(`import(a, b)`, `SyntaxError: Unexpected token ','. import call expects exactly one argument.`);
+testSyntaxError(`import(a, b, c)`, `SyntaxError: Unexpected token ','. import call expects exactly one argument.`);
+testSyntaxError(`import(...a)`, `SyntaxError: Unexpected token '...'`);
+testSyntaxError(`import(,a)`, `SyntaxError: Unexpected token ','`);
+testSyntaxError(`import(,)`, `SyntaxError: Unexpected token ','`);
+testSyntaxError(`import("Hello";`, `SyntaxError: Unexpected token ';'. import call expects exactly one argument.`);
+testSyntaxError(`import("Hello"];`, `SyntaxError: Unexpected token ']'. import call expects exactly one argument.`);
+testSyntaxError(`import("Hello",;`, `SyntaxError: Unexpected token ','. import call expects exactly one argument.`);
+testSyntaxError(`import("Hello", "Hello2";`, `SyntaxError: Unexpected token ','. import call expects exactly one argument.`);
+
+
+testSyntaxError(`import = 42`, `SyntaxError: Unexpected token '='. import call expects exactly one argument.`);
+testSyntaxError(`[import] = 42`, `SyntaxError: Unexpected token ']'. import call expects exactly one argument.`);
+testSyntaxError(`{import} = 42`, `SyntaxError: Unexpected token '}'. import call expects exactly one argument.`);
+testSyntaxError(`let import = 42`, `SyntaxError: Unexpected keyword 'import'`);
+testSyntaxError(`var import = 42`, `SyntaxError: Cannot use the keyword 'import' as a variable name.`);
+testSyntaxError(`const import = 42`, `SyntaxError: Cannot use the keyword 'import' as a lexical variable name.`);
+
+(async function () {
+ await testSyntax(`import("./import-tests/cocoa.js")`);
+ await testSyntax(`import("./import-tests/../import-tests/cocoa.js")`);
+}()).catch((error) => {
+ print(String(error));
+ abort();
+});
Added: trunk/JSTests/stress/import-tests/cocoa.js (0 => 210522)
--- trunk/JSTests/stress/import-tests/cocoa.js (rev 0)
+++ trunk/JSTests/stress/import-tests/cocoa.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,7 @@
+export class Cocoa {
+}
+
+export function hello()
+{
+ return 42;
+}
Added: trunk/JSTests/stress/import-tests/multiple.js (0 => 210522)
--- trunk/JSTests/stress/import-tests/multiple.js (rev 0)
+++ trunk/JSTests/stress/import-tests/multiple.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,4 @@
+export function result()
+{
+ return import('./multiple2.js');
+}
Added: trunk/JSTests/stress/import-tests/multiple2.js (0 => 210522)
--- trunk/JSTests/stress/import-tests/multiple2.js (rev 0)
+++ trunk/JSTests/stress/import-tests/multiple2.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,4 @@
+export function ok()
+{
+ return 42;
+}
Added: trunk/JSTests/stress/import-tests/should.js (0 => 210522)
--- trunk/JSTests/stress/import-tests/should.js (rev 0)
+++ trunk/JSTests/stress/import-tests/should.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -0,0 +1,19 @@
+export function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error(`bad value: ${String(actual)}`);
+}
+
+export function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
Modified: trunk/JSTests/stress/modules-syntax-error.js (210521 => 210522)
--- trunk/JSTests/stress/modules-syntax-error.js 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/JSTests/stress/modules-syntax-error.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -107,25 +107,25 @@
function noTopLevel() {
import * as from from "Cocoa"
}
-`, `SyntaxError: Unexpected keyword 'import':3`);
+`, `SyntaxError: Unexpected token '*'. import call expects exactly one argument.:3`);
checkModuleSyntaxError(String.raw`
if (noTopLevel) {
import * as from from "Cocoa"
}
-`, `SyntaxError: Unexpected keyword 'import':3`);
+`, `SyntaxError: Unexpected token '*'. import call expects exactly one argument.:3`);
checkModuleSyntaxError(String.raw`
{
import * as from from "Cocoa"
}
-`, `SyntaxError: Unexpected keyword 'import':3`);
+`, `SyntaxError: Unexpected token '*'. import call expects exactly one argument.:3`);
checkModuleSyntaxError(String.raw`
for (var i = 0; i < 1000; ++i) {
import * as from from "Cocoa"
}
-`, `SyntaxError: Unexpected keyword 'import':3`);
+`, `SyntaxError: Unexpected token '*'. import call expects exactly one argument.:3`);
checkModuleSyntaxError(String.raw`
import for from "Cocoa";
Modified: trunk/LayoutTests/ChangeLog (210521 => 210522)
--- trunk/LayoutTests/ChangeLog 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/LayoutTests/ChangeLog 2017-01-09 22:02:47 UTC (rev 210522)
@@ -1,3 +1,12 @@
+2017-01-09 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Prototype dynamic-import
+ https://bugs.webkit.org/show_bug.cgi?id=165724
+
+ Reviewed by Saam Barati.
+
+ * sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt:
+
2017-01-09 Andy Estes <aes...@apple.com>
[QuickLook] Add a layout test for webkit.org/b/135651
Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt (210521 => 210522)
--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt 2017-01-09 22:02:47 UTC (rev 210522)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 76: SyntaxError: Unexpected keyword 'import'
+CONSOLE MESSAGE: line 76: SyntaxError: Unexpected token '='. import call expects exactly one argument.
S7.5.3_A1.16
PASS Expected parsing failure
Modified: trunk/Source/_javascript_Core/ChangeLog (210521 => 210522)
--- trunk/Source/_javascript_Core/ChangeLog 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-01-09 22:02:47 UTC (rev 210522)
@@ -1,3 +1,102 @@
+2017-01-09 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Prototype dynamic-import
+ https://bugs.webkit.org/show_bug.cgi?id=165724
+
+ Reviewed by Saam Barati.
+
+ In this patch, we implement stage3 dynamic-import proposal[1].
+ This patch adds a new special operator `import`. And by using it, we can import
+ the module dynamically from modules and scripts. Before this feature, the module
+ is always imported statically and before executing the modules, importing the modules
+ needs to be done. And especially, the module can only be imported from the module.
+ So the classic script cannot import and use the modules. This dynamic-import relaxes
+ the above restrictions.
+
+ The typical dynamic-import form is the following.
+
+ import("...").then(function (namespace) { ... });
+
+ You can pass any AssignmentExpression for the import operator. So you can determine
+ the importing modules dynamically.
+
+ import(value).then(function (namespace) { ... });
+
+ And previously the module import declaration is only allowed in the top level statements.
+ But this import operator is just an _expression_. So you can use it in the function.
+ And you can use it conditionally.
+
+ async function go(cond)
+ {
+ if (cond)
+ return import("...");
+ return undefined;
+ }
+ await go(true);
+
+ Currently, this patch just implements this feature only for the JSC shell.
+ JSC module loader requires a new hook, `importModule`. And the JSC shell implements
+ this hook. So, for now, this dynamic-import is not available in the browser side.
+ If you write this `import` call, it always returns the rejected promise.
+
+ import is implemented like a special operator similar to `super`.
+ This is because import is context-sensitive. If you call the `import`, the module
+ key resolution is done based on the caller's running context.
+
+ For example, if you are running the script which filename is "./ok/hello.js", the module
+ key for the call`import("./resource/syntax.js")` becomes `"./ok/resource/syntax.js"`.
+ But if you write the completely same import form in the script "./error/hello.js", the
+ key becomes "./error/resource/syntax.js". So exposing this feature as the `import`
+ function is misleading: this function becomes caller's context-sensitive. That's why
+ dynamic-import is specified as a special operator.
+
+ To resolve the module key, we need the caller's context information like the filename of
+ the caller. This is provided by the SourceOrigin implemented in r210149.
+ In the JSC shell implementation, this SourceOrigin holds the filename of the caller. So
+ based on this implementation, the module loader resolve the module key.
+ In the near future, we will extend this SourceOrigin to hold more information needed for
+ the browser-side import implementation.
+
+ [1]: https://tc39.github.io/proposal-dynamic-import/
+
+ * builtins/ModuleLoaderPrototype.js:
+ (importModule):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitGetTemplateObject):
+ (JSC::BytecodeGenerator::emitGetGlobalPrivate):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ImportNode::emitBytecode):
+ * jsc.cpp:
+ (absolutePath):
+ (GlobalObject::moduleLoaderImportModule):
+ (functionRun):
+ (functionLoad):
+ (functionCheckSyntax):
+ (runWithScripts):
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createImportExpr):
+ * parser/NodeConstructors.h:
+ (JSC::ImportNode::ImportNode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::isImportNode):
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseMemberExpression):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createImportExpr):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncImportModule):
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSModuleLoader.cpp:
+ (JSC::JSModuleLoader::importModule):
+ (JSC::JSModuleLoader::getModuleNamespaceObject):
+ * runtime/JSModuleLoader.h:
+ * runtime/ModuleLoaderPrototype.cpp:
+ (JSC::moduleLoaderPrototypeGetModuleNamespaceObject):
+
2017-01-08 Filip Pizlo <fpi...@apple.com>
Make the collector's fixpoint smart about scheduling work
Modified: trunk/Source/_javascript_Core/builtins/ModuleLoaderPrototype.js (210521 => 210522)
--- trunk/Source/_javascript_Core/builtins/ModuleLoaderPrototype.js 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/builtins/ModuleLoaderPrototype.js 2017-01-09 22:02:47 UTC (rev 210522)
@@ -470,3 +470,19 @@
this.link(entry, initiator);
return this.moduleEvaluation(entry.module, initiator);
}
+
+function importModule(moduleName, referrer, initiator)
+{
+ "use strict";
+
+ // Loader.resolve hook point.
+ // resolve: moduleName => Promise(moduleKey)
+ // Take the name and resolve it to the unique identifier for the resource location.
+ // For example, take the "jquery" and return the URL for the resource.
+ return this.resolve(moduleName, referrer, initiator).then((key) => {
+ return this.requestInstantiateAll(key, initiator);
+ }).then((entry) => {
+ this.linkAndEvaluateModule(entry.key, initiator);
+ return this.getModuleNamespaceObject(entry.module);
+ });
+}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -4261,22 +4261,24 @@
cookedStrings.append(templateString->value()->cooked().impl());
}
- RefPtr<RegisterID> getTemplateObject = nullptr;
- Variable var = variable(propertyNames().builtinNames().getTemplateObjectPrivateName());
- if (RegisterID* local = var.local())
- getTemplateObject = emitMove(newTemporary(), local);
- else {
- getTemplateObject = newTemporary();
- RefPtr<RegisterID> scope = newTemporary();
- moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), var));
- emitGetFromScope(getTemplateObject.get(), scope.get(), var, ThrowIfNotFound);
- }
-
+ RefPtr<RegisterID> getTemplateObject = emitGetGlobalPrivate(newTemporary(), propertyNames().builtinNames().getTemplateObjectPrivateName());
CallArguments arguments(*this, nullptr);
emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(m_vm->templateRegistryKeyTable().createKey(rawStrings, cookedStrings))));
return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd(), DebuggableCall::No);
}
+RegisterID* BytecodeGenerator::emitGetGlobalPrivate(RegisterID* dst, const Identifier& property)
+{
+ dst = tempDestination(dst);
+ Variable var = variable(property);
+ if (RegisterID* local = var.local())
+ return emitMove(dst, local);
+
+ RefPtr<RegisterID> scope = newTemporary();
+ moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), var));
+ return emitGetFromScope(dst, scope.get(), var, ThrowIfNotFound);
+}
+
RegisterID* BytecodeGenerator::emitGetEnumerableLength(RegisterID* dst, RegisterID* base)
{
emitOpcode(op_get_enumerable_length);
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (210521 => 210522)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -678,6 +678,7 @@
void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, ForOfNode* = nullptr, RegisterID* forLoopSymbolTable = nullptr);
RegisterID* emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode*);
+ RegisterID* emitGetGlobalPrivate(RegisterID* dst, const Identifier& property);
enum class ReturnFrom { Normal, Finally };
RegisterID* emitReturn(RegisterID* src, ReturnFrom = ReturnFrom::Normal);
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -190,6 +190,17 @@
return generator.moveToDestinationIfNeeded(generator.finalDestination(dst), result);
}
+// ------------------------------ ImportNode -------------------------------------
+
+RegisterID* ImportNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> importModule = generator.emitGetGlobalPrivate(generator.newTemporary(), generator.propertyNames().builtinNames().importModulePrivateName());
+ CallArguments arguments(generator, nullptr, 1);
+ generator.emitLoad(arguments.thisRegister(), jsUndefined());
+ generator.emitNode(arguments.argumentRegister(0), m_expr);
+ return generator.emitCall(generator.finalDestination(dst, importModule.get()), importModule.get(), NoExpectedFunction, arguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
+}
+
// ------------------------------ NewTargetNode ----------------------------------
RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
Modified: trunk/Source/_javascript_Core/jsc.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/jsc.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/jsc.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -25,6 +25,7 @@
#include "ArrayBuffer.h"
#include "ArrayPrototype.h"
#include "BuiltinExecutableCreator.h"
+#include "BuiltinNames.h"
#include "ButterflyInlines.h"
#include "CodeBlock.h"
#include "Completion.h"
@@ -48,6 +49,7 @@
#include "JSInternalPromise.h"
#include "JSInternalPromiseDeferred.h"
#include "JSLock.h"
+#include "JSModuleLoader.h"
#include "JSNativeStdFunction.h"
#include "JSONObject.h"
#include "JSProxy.h"
@@ -1101,10 +1103,10 @@
}
template<typename Vector>
-static inline SourceCode jscSource(const Vector& utf8, const String& filename)
+static inline SourceCode jscSource(const Vector& utf8, const SourceOrigin& sourceOrigin, const String& filename)
{
String str = stringFromUTF(utf8);
- return makeSource(str, SourceOrigin { filename }, filename);
+ return makeSource(str, sourceOrigin, filename);
}
class GlobalObject : public JSGlobalObject {
@@ -1277,6 +1279,7 @@
putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function, NoIntrinsic, function));
}
+ static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, const SourceOrigin&);
static JSInternalPromise* moduleLoaderResolve(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue);
};
@@ -1288,6 +1291,7 @@
&_javascript_RuntimeFlags,
nullptr,
&shouldInterruptScriptBeforeTimeout,
+ &moduleLoaderImportModule,
&moduleLoaderResolve,
&moduleLoaderFetch,
nullptr,
@@ -1420,6 +1424,29 @@
return builder.toString();
}
+static String absolutePath(const String& fileName)
+{
+ auto directoryName = currentWorkingDirectory();
+ if (!directoryName)
+ return fileName;
+ return resolvePath(directoryName.value(), ModuleName(fileName.impl()));
+}
+
+JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject*, ExecState* exec, JSModuleLoader* moduleLoader, JSString* moduleName, const SourceOrigin& sourceOrigin)
+{
+ auto* function = jsCast<JSObject*>(moduleLoader->get(exec, exec->propertyNames().builtinNames().importModulePublicName()));
+ CallData callData;
+ auto callType = JSC::getCallData(function, callData);
+ ASSERT(callType != CallType::None);
+
+ MarkedArgumentBuffer arguments;
+ arguments.append(moduleName);
+ arguments.append(jsString(exec, sourceOrigin.string()));
+ arguments.append(jsUndefined());
+
+ return jsCast<JSInternalPromise*>(call(exec, function, callType, callData, moduleLoader, arguments));
+}
+
JSInternalPromise* GlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue)
{
VM& vm = globalObject->vm();
@@ -1924,7 +1951,7 @@
NakedPtr<Exception> exception;
StopWatch stopWatch;
stopWatch.start();
- evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), exception);
+ evaluate(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), exception);
stopWatch.stop();
if (exception) {
@@ -1976,7 +2003,7 @@
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
NakedPtr<Exception> evaluationException;
- JSValue result = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), evaluationException);
+ JSValue result = evaluate(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), evaluationException);
if (evaluationException)
throwException(exec, scope, evaluationException);
return JSValue::encode(result);
@@ -2047,7 +2074,7 @@
stopWatch.start();
JSValue syntaxException;
- bool validSyntax = checkSyntax(globalObject->globalExec(), jscSource(script, fileName), &syntaxException);
+ bool validSyntax = checkSyntax(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), &syntaxException);
stopWatch.stop();
if (!validSyntax)
@@ -2909,7 +2936,7 @@
bool isLastFile = i == scripts.size() - 1;
if (isModule) {
if (!promise)
- promise = loadAndEvaluateModule(globalObject->globalExec(), jscSource(scriptBuffer, fileName));
+ promise = loadAndEvaluateModule(globalObject->globalExec(), jscSource(scriptBuffer, SourceOrigin { absolutePath(fileName) }, fileName));
scope.clearException();
JSFunction* fulfillHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&, isLastFile](ExecState* exec) {
@@ -2926,7 +2953,7 @@
vm.drainMicrotasks();
} else {
NakedPtr<Exception> evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(scriptBuffer, fileName), JSValue(), evaluationException);
+ JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(scriptBuffer, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), evaluationException);
ASSERT(!scope.exception());
if (evaluationException)
returnValue = evaluationException->value();
@@ -2999,7 +3026,7 @@
break;
NakedPtr<Exception> evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line, sourceOrigin.string()), JSValue(), evaluationException);
+ JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line, sourceOrigin, sourceOrigin.string()), JSValue(), evaluationException);
#endif
if (evaluationException)
printf("Exception: %s\n", evaluationException->value().toWTFString(globalObject->globalExec()).utf8().data());
Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (210521 => 210522)
--- trunk/Source/_javascript_Core/parser/ASTBuilder.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -178,6 +178,12 @@
{
return new (m_parserArena) SuperNode(location);
}
+ ExpressionNode* createImportExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
+ {
+ auto* node = new (m_parserArena) ImportNode(location, expr);
+ setExceptionLocation(node, start, divot, end);
+ return node;
+ }
ExpressionNode* createNewTargetExpr(const JSTokenLocation location)
{
usesNewTarget();
Modified: trunk/Source/_javascript_Core/parser/NodeConstructors.h (210521 => 210522)
--- trunk/Source/_javascript_Core/parser/NodeConstructors.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/parser/NodeConstructors.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -167,6 +167,12 @@
{
}
+ inline ImportNode::ImportNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location)
+ , m_expr(expr)
+ {
+ }
+
inline NewTargetNode::NewTargetNode(const JSTokenLocation& location)
: ExpressionNode(location)
{
Modified: trunk/Source/_javascript_Core/parser/Nodes.h (210521 => 210522)
--- trunk/Source/_javascript_Core/parser/Nodes.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/parser/Nodes.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -186,6 +186,7 @@
virtual bool isBoolean() const { return false; }
virtual bool isSpreadExpression() const { return false; }
virtual bool isSuperNode() const { return false; }
+ virtual bool isImportNode() const { return false; }
virtual bool isNewTarget() const { return false; }
virtual bool isBytecodeIntrinsicNode() const { return false; }
@@ -570,6 +571,17 @@
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
+ class ImportNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ ImportNode(const JSTokenLocation&, ExpressionNode*);
+
+ private:
+ bool isImportNode() const override { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ };
+
class NewTargetNode final : public ExpressionNode {
public:
NewTargetNode(const JSTokenLocation&);
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -4343,7 +4343,8 @@
}
bool baseIsSuper = match(SUPER);
- semanticFailIfTrue(baseIsSuper && newCount, "Cannot use new with super");
+ bool baseIsImport = match(IMPORT);
+ semanticFailIfTrue((baseIsSuper || baseIsImport) && newCount, "Cannot use new with ", getToken());
bool baseIsNewTarget = false;
if (newCount && match(DOT)) {
@@ -4383,6 +4384,14 @@
semanticFailIfTrue(functionSuperBinding == SuperBinding::NotNeeded, "super is not valid in this context");
}
}
+ } else if (baseIsImport) {
+ JSTextPosition expressionEnd = lastTokenEndPosition();
+ next();
+ consumeOrFail(OPENPAREN, "import call expects exactly one argument");
+ TreeExpression expr = parseAssignmentExpression(context);
+ failIfFalse(expr, "Cannot parse _expression_");
+ consumeOrFail(CLOSEPAREN, "import call expects exactly one argument");
+ return context.createImportExpr(location, expr, expressionStart, expressionEnd, lastTokenEndPosition());
} else if (!baseIsNewTarget) {
const bool isAsync = match(ASYNC);
Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (210521 => 210522)
--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -71,7 +71,7 @@
enum { NoneExpr = 0,
ResolveEvalExpr, ResolveExpr, IntegerExpr, DoubleExpr, StringExpr,
ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
- FunctionExpr, ClassExpr, SuperExpr, BracketExpr, DotExpr, CallExpr,
+ FunctionExpr, ClassExpr, SuperExpr, ImportExpr, BracketExpr, DotExpr, CallExpr,
NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
ConditionalExpr, AssignmentExpr, TypeofExpr, NewTargetExpr,
DeleteExpr, ArrayLiteralExpr, BindingDestructuring, RestParameter,
@@ -156,6 +156,7 @@
ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType createImportExpr(const JSTokenLocation&, ExpressionType, int, int, int) { return ImportExpr; }
ExpressionType createThisExpr(const JSTokenLocation&) { return ThisExpr; }
ExpressionType createSuperExpr(const JSTokenLocation&) { return SuperExpr; }
ExpressionType createNewTargetExpr(const JSTokenLocation&) { return NewTargetExpr; }
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -256,6 +256,7 @@
nullptr,
nullptr,
nullptr,
+ nullptr,
nullptr
};
@@ -732,6 +733,7 @@
JSFunction* privateFuncTrunc = JSFunction::create(vm, this, 0, String(), mathProtoFuncTrunc, TruncIntrinsic);
JSFunction* privateFuncGetTemplateObject = JSFunction::create(vm, this, 0, String(), getTemplateObject);
+ JSFunction* privateFuncImportModule = JSFunction::create(vm, this, 0, String(), globalFuncImportModule);
JSFunction* privateFuncTypedArrayLength = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncLength);
JSFunction* privateFuncTypedArrayGetOriginalConstructor = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncGetOriginalConstructor);
JSFunction* privateFuncTypedArraySort = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncSort);
@@ -785,6 +787,7 @@
GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().ownEnumerablePropertyKeysPrivateName(), JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().getTemplateObjectPrivateName(), privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().importModulePrivateName(), privateFuncImportModule, DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().enqueueJobPrivateName(), JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().ErrorPrivateName(), m_errorConstructor.get(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().RangeErrorPrivateName(), m_rangeErrorConstructor.get(), DontEnum | DontDelete | ReadOnly),
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -184,6 +184,9 @@
typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*);
ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout;
+ typedef JSInternalPromise* (*ModuleLoaderImportModulePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, const SourceOrigin&);
+ ModuleLoaderImportModulePtr moduleLoaderImportModule;
+
typedef JSInternalPromise* (*ModuleLoaderResolvePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
ModuleLoaderResolvePtr moduleLoaderResolve;
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -27,10 +27,14 @@
#include "CallFrame.h"
#include "EvalExecutable.h"
+#include "Exception.h"
#include "IndirectEvalExecutable.h"
#include "Interpreter.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "JSInternalPromise.h"
+#include "JSModuleLoader.h"
+#include "JSPromiseDeferred.h"
#include "JSString.h"
#include "JSStringBuilder.h"
#include "Lexer.h"
@@ -925,4 +929,39 @@
return JSValue::encode(jsUndefined());
}
+EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto catchScope = DECLARE_CATCH_SCOPE(vm);
+
+ auto* globalObject = exec->lexicalGlobalObject();
+
+ auto* promise = JSPromiseDeferred::create(exec, globalObject);
+ RETURN_IF_EXCEPTION(catchScope, { });
+
+ auto sourceOrigin = exec->callerSourceOrigin();
+ if (sourceOrigin.isNull()) {
+ promise->reject(exec, createError(exec, ASCIILiteral("Could not resolve the module specifier.")));
+ return JSValue::encode(promise->promise());
+ }
+
+ RELEASE_ASSERT(exec->argumentCount() == 1);
+ auto* specifier = exec->uncheckedArgument(0).toString(exec);
+ if (Exception* exception = catchScope.exception()) {
+ catchScope.clearException();
+ promise->reject(exec, exception);
+ return JSValue::encode(promise->promise());
+ }
+
+ auto* internalPromise = globalObject->moduleLoader()->importModule(exec, specifier, sourceOrigin);
+ if (Exception* exception = catchScope.exception()) {
+ catchScope.clearException();
+ promise->reject(exec, exception);
+ return JSValue::encode(promise->promise());
+ }
+ promise->resolve(exec, internalPromise);
+
+ return JSValue::encode(promise->promise());
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -50,6 +50,7 @@
EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*);
static const double mantissaOverflowLowerBound = 9007199254740992.0;
double parseIntOverflow(const LChar*, unsigned length, int radix);
Modified: trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -134,6 +134,30 @@
return call(exec, function, callType, callData, this, arguments);
}
+JSInternalPromise* JSModuleLoader::importModule(ExecState* exec, JSString* moduleName, const SourceOrigin& referrer)
+{
+ if (Options::dumpModuleLoadingState())
+ dataLog("Loader [import] ", printableModuleKey(exec, moduleName), "\n");
+
+ auto* globalObject = exec->lexicalGlobalObject();
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+
+ if (globalObject->globalObjectMethodTable()->moduleLoaderImportModule)
+ return globalObject->globalObjectMethodTable()->moduleLoaderImportModule(globalObject, exec, this, moduleName, referrer);
+
+ auto* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
+ auto moduleNameString = moduleName->value(exec);
+ if (UNLIKELY(scope.exception())) {
+ JSValue exception = scope.exception()->value();
+ scope.clearException();
+ deferred->reject(exec, exception);
+ return deferred->promise();
+ }
+ deferred->reject(exec, createError(exec, makeString("Could not import the module '", moduleNameString, "'.")));
+ return deferred->promise();
+}
+
JSInternalPromise* JSModuleLoader::resolve(ExecState* exec, JSValue name, JSValue referrer, JSValue initiator)
{
if (Options::dumpModuleLoadingState())
@@ -197,4 +221,19 @@
return moduleRecord->evaluate(exec);
}
+JSModuleNamespaceObject* JSModuleLoader::getModuleNamespaceObject(ExecState* exec, JSValue moduleRecordValue)
+{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(moduleRecordValue);
+ if (!moduleRecord) {
+ throwTypeError(exec, scope);
+ return nullptr;
+ }
+
+ scope.release();
+ return moduleRecord->getModuleNamespace(exec);
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSModuleLoader.h (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/JSModuleLoader.h 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/JSModuleLoader.h 2017-01-09 22:02:47 UTC (rev 210522)
@@ -31,6 +31,7 @@
namespace JSC {
class JSInternalPromise;
+class JSModuleNamespaceObject;
class JSModuleLoader : public JSNonFinalObject {
private:
@@ -67,6 +68,7 @@
JSValue linkAndEvaluateModule(ExecState*, JSValue moduleKey, JSValue initiator);
// Platform dependent hooked APIs.
+ JSInternalPromise* importModule(ExecState*, JSString* moduleName, const SourceOrigin& referrer);
JSInternalPromise* resolve(ExecState*, JSValue name, JSValue referrer, JSValue initiator);
JSInternalPromise* fetch(ExecState*, JSValue key, JSValue initiator);
JSInternalPromise* instantiate(ExecState*, JSValue key, JSValue source, JSValue initiator);
@@ -74,6 +76,9 @@
// Additional platform dependent hooked APIs.
JSValue evaluate(ExecState*, JSValue key, JSValue moduleRecord, JSValue initiator);
+ // Utility functions.
+ JSModuleNamespaceObject* getModuleNamespaceObject(ExecState*, JSValue moduleRecord);
+
protected:
void finishCreation(ExecState*, VM&, JSGlobalObject*);
};
Modified: trunk/Source/_javascript_Core/runtime/ModuleLoaderPrototype.cpp (210521 => 210522)
--- trunk/Source/_javascript_Core/runtime/ModuleLoaderPrototype.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/_javascript_Core/runtime/ModuleLoaderPrototype.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -37,6 +37,7 @@
#include "JSMap.h"
#include "JSModuleEnvironment.h"
#include "JSModuleLoader.h"
+#include "JSModuleNamespaceObject.h"
#include "JSModuleRecord.h"
#include "ModuleAnalyzer.h"
#include "Nodes.h"
@@ -52,6 +53,7 @@
static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeResolve(ExecState*);
static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeFetch(ExecState*);
static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeInstantiate(ExecState*);
+static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeGetModuleNamespaceObject(ExecState*);
}
@@ -85,6 +87,8 @@
loadAndEvaluateModule JSBuiltin DontEnum|Function 3
loadModule JSBuiltin DontEnum|Function 3
linkAndEvaluateModule JSBuiltin DontEnum|Function 2
+ importModule JSBuiltin DontEnum|Function 3
+ getModuleNamespaceObject moduleLoaderPrototypeGetModuleNamespaceObject DontEnum|Function 1
parseModule moduleLoaderPrototypeParseModule DontEnum|Function 2
requestedModules moduleLoaderPrototypeRequestedModules DontEnum|Function 1
resolve moduleLoaderPrototypeResolve DontEnum|Function 2
@@ -211,6 +215,19 @@
return JSValue::encode(loader->instantiate(exec, exec->argument(0), exec->argument(1), exec->argument(2)));
}
+EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeGetModuleNamespaceObject(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* loader = jsDynamicCast<JSModuleLoader*>(exec->thisValue());
+ if (!loader)
+ return JSValue::encode(jsUndefined());
+ auto* moduleNamespaceObject = loader->getModuleNamespaceObject(exec, exec->argument(0));
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ return JSValue::encode(moduleNamespaceObject);
+}
+
// ------------------- Additional Hook Functions ---------------------------
EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeEvaluate(ExecState* exec)
Modified: trunk/Source/WebCore/ChangeLog (210521 => 210522)
--- trunk/Source/WebCore/ChangeLog 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/WebCore/ChangeLog 2017-01-09 22:02:47 UTC (rev 210522)
@@ -1,3 +1,16 @@
+2017-01-09 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Prototype dynamic-import
+ https://bugs.webkit.org/show_bug.cgi?id=165724
+
+ Reviewed by Saam Barati.
+
+ We do not set a handler for import for now.
+ So dynamic import feature is only enabled in the JSC shell right now.
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ * bindings/js/JSWorkerGlobalScopeBase.cpp:
+
2017-01-09 Youenn Fablet <youe...@gmail.com>
Merging ThreadableLoader redundant options on filtering responses
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (210521 => 210522)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -64,6 +64,7 @@
&_javascript_RuntimeFlags,
&queueTaskToEventLoop,
&shouldInterruptScriptBeforeTimeout,
+ nullptr,
&moduleLoaderResolve,
&moduleLoaderFetch,
nullptr,
Modified: trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp (210521 => 210522)
--- trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp 2017-01-09 21:45:56 UTC (rev 210521)
+++ trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp 2017-01-09 22:02:47 UTC (rev 210522)
@@ -57,6 +57,7 @@
nullptr,
nullptr,
nullptr,
+ nullptr,
&defaultLanguage
};