1/*
2 * Copyright (C) 2015-2018 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "JSModuleLoader.h"
29
30#include "BuiltinNames.h"
31#include "CatchScope.h"
32#include "CodeProfiling.h"
33#include "Error.h"
34#include "Exception.h"
35#include "JSCInlines.h"
36#include "JSGlobalObjectFunctions.h"
37#include "JSInternalPromise.h"
38#include "JSInternalPromiseDeferred.h"
39#include "JSMap.h"
40#include "JSModuleEnvironment.h"
41#include "JSModuleNamespaceObject.h"
42#include "JSModuleRecord.h"
43#include "JSSourceCode.h"
44#include "ModuleAnalyzer.h"
45#include "Nodes.h"
46#include "ObjectConstructor.h"
47#include "Parser.h"
48#include "ParserError.h"
49#include "WebAssemblyPrototype.h"
50
51namespace JSC {
52
53static EncodedJSValue JSC_HOST_CALL moduleLoaderParseModule(ExecState*);
54static EncodedJSValue JSC_HOST_CALL moduleLoaderRequestedModules(ExecState*);
55static EncodedJSValue JSC_HOST_CALL moduleLoaderEvaluate(ExecState*);
56static EncodedJSValue JSC_HOST_CALL moduleLoaderModuleDeclarationInstantiation(ExecState*);
57static EncodedJSValue JSC_HOST_CALL moduleLoaderResolve(ExecState*);
58static EncodedJSValue JSC_HOST_CALL moduleLoaderResolveSync(ExecState*);
59static EncodedJSValue JSC_HOST_CALL moduleLoaderFetch(ExecState*);
60static EncodedJSValue JSC_HOST_CALL moduleLoaderGetModuleNamespaceObject(ExecState*);
61
62}
63
64#include "JSModuleLoader.lut.h"
65
66namespace JSC {
67
68STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSModuleLoader);
69
70const ClassInfo JSModuleLoader::s_info = { "ModuleLoader", &Base::s_info, &moduleLoaderTable, nullptr, CREATE_METHOD_TABLE(JSModuleLoader) };
71
72/* Source for JSModuleLoader.lut.h
73@begin moduleLoaderTable
74 ensureRegistered JSBuiltin DontEnum|Function 1
75 forceFulfillPromise JSBuiltin DontEnum|Function 2
76 fulfillFetch JSBuiltin DontEnum|Function 2
77 requestFetch JSBuiltin DontEnum|Function 3
78 requestInstantiate JSBuiltin DontEnum|Function 3
79 requestSatisfy JSBuiltin DontEnum|Function 3
80 link JSBuiltin DontEnum|Function 2
81 moduleDeclarationInstantiation moduleLoaderModuleDeclarationInstantiation DontEnum|Function 2
82 moduleEvaluation JSBuiltin DontEnum|Function 2
83 evaluate moduleLoaderEvaluate DontEnum|Function 3
84 provideFetch JSBuiltin DontEnum|Function 2
85 loadAndEvaluateModule JSBuiltin DontEnum|Function 3
86 loadModule JSBuiltin DontEnum|Function 3
87 linkAndEvaluateModule JSBuiltin DontEnum|Function 2
88 requestImportModule JSBuiltin DontEnum|Function 3
89 getModuleNamespaceObject moduleLoaderGetModuleNamespaceObject DontEnum|Function 1
90 parseModule moduleLoaderParseModule DontEnum|Function 2
91 requestedModules moduleLoaderRequestedModules DontEnum|Function 1
92 resolve moduleLoaderResolve DontEnum|Function 2
93 resolveSync moduleLoaderResolveSync DontEnum|Function 2
94 fetch moduleLoaderFetch DontEnum|Function 3
95@end
96*/
97
98JSModuleLoader::JSModuleLoader(VM& vm, Structure* structure)
99 : JSNonFinalObject(vm, structure)
100{
101}
102
103void JSModuleLoader::finishCreation(ExecState* exec, VM& vm, JSGlobalObject* globalObject)
104{
105 auto scope = DECLARE_CATCH_SCOPE(vm);
106
107 Base::finishCreation(vm);
108 ASSERT(inherits(vm, info()));
109 JSMap* map = JSMap::create(exec, vm, globalObject->mapStructure());
110 scope.releaseAssertNoException();
111 putDirect(vm, Identifier::fromString(&vm, "registry"), map);
112}
113
114// ------------------------------ Functions --------------------------------
115
116static String printableModuleKey(ExecState* exec, JSValue key)
117{
118 VM& vm = exec->vm();
119 auto scope = DECLARE_THROW_SCOPE(vm);
120 if (key.isString() || key.isSymbol()) {
121 auto propertyName = key.toPropertyKey(exec);
122 scope.assertNoException(); // This is OK since this function is just for debugging purpose.
123 return propertyName.impl();
124 }
125 return vm.propertyNames->emptyIdentifier.impl();
126}
127
128JSValue JSModuleLoader::provideFetch(ExecState* exec, JSValue key, const SourceCode& sourceCode)
129{
130 VM& vm = exec->vm();
131 auto scope = DECLARE_THROW_SCOPE(vm);
132
133 JSObject* function = jsCast<JSObject*>(get(exec, vm.propertyNames->builtinNames().provideFetchPublicName()));
134 RETURN_IF_EXCEPTION(scope, { });
135 CallData callData;
136 CallType callType = JSC::getCallData(vm, function, callData);
137 ASSERT(callType != CallType::None);
138
139 SourceCode source { sourceCode };
140 MarkedArgumentBuffer arguments;
141 arguments.append(key);
142 arguments.append(JSSourceCode::create(vm, WTFMove(source)));
143 ASSERT(!arguments.hasOverflowed());
144
145 RELEASE_AND_RETURN(scope, call(exec, function, callType, callData, this, arguments));
146}
147
148JSInternalPromise* JSModuleLoader::loadAndEvaluateModule(ExecState* exec, JSValue moduleName, JSValue parameters, JSValue scriptFetcher)
149{
150 VM& vm = exec->vm();
151 auto scope = DECLARE_THROW_SCOPE(vm);
152
153 JSObject* function = jsCast<JSObject*>(get(exec, vm.propertyNames->builtinNames().loadAndEvaluateModulePublicName()));
154 RETURN_IF_EXCEPTION(scope, nullptr);
155 CallData callData;
156 CallType callType = JSC::getCallData(vm, function, callData);
157 ASSERT(callType != CallType::None);
158
159 MarkedArgumentBuffer arguments;
160 arguments.append(moduleName);
161 arguments.append(parameters);
162 arguments.append(scriptFetcher);
163 ASSERT(!arguments.hasOverflowed());
164
165 JSValue promise = call(exec, function, callType, callData, this, arguments);
166 RETURN_IF_EXCEPTION(scope, nullptr);
167 return jsCast<JSInternalPromise*>(promise);
168}
169
170JSInternalPromise* JSModuleLoader::loadModule(ExecState* exec, JSValue moduleName, JSValue parameters, JSValue scriptFetcher)
171{
172 VM& vm = exec->vm();
173 auto scope = DECLARE_THROW_SCOPE(vm);
174
175 JSObject* function = jsCast<JSObject*>(get(exec, vm.propertyNames->builtinNames().loadModulePublicName()));
176 RETURN_IF_EXCEPTION(scope, nullptr);
177 CallData callData;
178 CallType callType = JSC::getCallData(vm, function, callData);
179 ASSERT(callType != CallType::None);
180
181 MarkedArgumentBuffer arguments;
182 arguments.append(moduleName);
183 arguments.append(parameters);
184 arguments.append(scriptFetcher);
185 ASSERT(!arguments.hasOverflowed());
186
187 JSValue promise = call(exec, function, callType, callData, this, arguments);
188 RETURN_IF_EXCEPTION(scope, nullptr);
189 return jsCast<JSInternalPromise*>(promise);
190}
191
192JSValue JSModuleLoader::linkAndEvaluateModule(ExecState* exec, JSValue moduleKey, JSValue scriptFetcher)
193{
194 VM& vm = exec->vm();
195 auto scope = DECLARE_THROW_SCOPE(vm);
196
197 JSObject* function = jsCast<JSObject*>(get(exec, vm.propertyNames->builtinNames().linkAndEvaluateModulePublicName()));
198 RETURN_IF_EXCEPTION(scope, { });
199 CallData callData;
200 CallType callType = JSC::getCallData(vm, function, callData);
201 ASSERT(callType != CallType::None);
202
203 MarkedArgumentBuffer arguments;
204 arguments.append(moduleKey);
205 arguments.append(scriptFetcher);
206 ASSERT(!arguments.hasOverflowed());
207
208 RELEASE_AND_RETURN(scope, call(exec, function, callType, callData, this, arguments));
209}
210
211JSInternalPromise* JSModuleLoader::requestImportModule(ExecState* exec, const Identifier& moduleKey, JSValue parameters, JSValue scriptFetcher)
212{
213 VM& vm = exec->vm();
214 auto scope = DECLARE_THROW_SCOPE(vm);
215
216 auto* function = jsCast<JSObject*>(get(exec, vm.propertyNames->builtinNames().requestImportModulePublicName()));
217 RETURN_IF_EXCEPTION(scope, nullptr);
218 CallData callData;
219 auto callType = JSC::getCallData(vm, function, callData);
220 ASSERT(callType != CallType::None);
221
222 MarkedArgumentBuffer arguments;
223 arguments.append(jsString(exec, moduleKey.impl()));
224 arguments.append(parameters);
225 arguments.append(scriptFetcher);
226 ASSERT(!arguments.hasOverflowed());
227
228 JSValue promise = call(exec, function, callType, callData, this, arguments);
229 RETURN_IF_EXCEPTION(scope, nullptr);
230 return jsCast<JSInternalPromise*>(promise);
231}
232
233JSInternalPromise* JSModuleLoader::importModule(ExecState* exec, JSString* moduleName, JSValue parameters, const SourceOrigin& referrer)
234{
235 if (Options::dumpModuleLoadingState())
236 dataLog("Loader [import] ", printableModuleKey(exec, moduleName), "\n");
237
238 auto* globalObject = exec->lexicalGlobalObject();
239 VM& vm = globalObject->vm();
240 auto throwScope = DECLARE_THROW_SCOPE(vm);
241
242 if (globalObject->globalObjectMethodTable()->moduleLoaderImportModule)
243 RELEASE_AND_RETURN(throwScope, globalObject->globalObjectMethodTable()->moduleLoaderImportModule(globalObject, exec, this, moduleName, parameters, referrer));
244
245 auto* deferred = JSInternalPromiseDeferred::tryCreate(exec, globalObject);
246 RETURN_IF_EXCEPTION(throwScope, nullptr);
247
248 auto catchScope = DECLARE_CATCH_SCOPE(vm);
249 auto moduleNameString = moduleName->value(exec);
250 if (UNLIKELY(catchScope.exception())) {
251 JSValue exception = catchScope.exception()->value();
252 catchScope.clearException();
253 deferred->reject(exec, exception);
254 catchScope.clearException();
255 return deferred->promise();
256 }
257 deferred->reject(exec, createError(exec, makeString("Could not import the module '", moduleNameString, "'.")));
258 catchScope.clearException();
259 return deferred->promise();
260}
261
262Identifier JSModuleLoader::resolveSync(ExecState* exec, JSValue name, JSValue referrer, JSValue scriptFetcher)
263{
264 if (Options::dumpModuleLoadingState())
265 dataLog("Loader [resolve] ", printableModuleKey(exec, name), "\n");
266
267 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
268 if (globalObject->globalObjectMethodTable()->moduleLoaderResolve)
269 return globalObject->globalObjectMethodTable()->moduleLoaderResolve(globalObject, exec, this, name, referrer, scriptFetcher);
270 return name.toPropertyKey(exec);
271}
272
273JSInternalPromise* JSModuleLoader::resolve(ExecState* exec, JSValue name, JSValue referrer, JSValue scriptFetcher)
274{
275 VM& vm = exec->vm();
276 auto throwScope = DECLARE_THROW_SCOPE(vm);
277
278 JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::tryCreate(exec, exec->lexicalGlobalObject());
279 RETURN_IF_EXCEPTION(throwScope, nullptr);
280
281 auto catchScope = DECLARE_CATCH_SCOPE(vm);
282
283 const Identifier moduleKey = resolveSync(exec, name, referrer, scriptFetcher);
284 if (UNLIKELY(catchScope.exception())) {
285 JSValue exception = catchScope.exception();
286 catchScope.clearException();
287 auto result = deferred->reject(exec, exception);
288 catchScope.clearException();
289 return result;
290 }
291 auto result = deferred->resolve(exec, identifierToJSValue(vm, moduleKey));
292 catchScope.clearException();
293 return result;
294}
295
296JSInternalPromise* JSModuleLoader::fetch(ExecState* exec, JSValue key, JSValue parameters, JSValue scriptFetcher)
297{
298 if (Options::dumpModuleLoadingState())
299 dataLog("Loader [fetch] ", printableModuleKey(exec, key), "\n");
300
301 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
302 VM& vm = globalObject->vm();
303 auto throwScope = DECLARE_THROW_SCOPE(vm);
304
305 if (globalObject->globalObjectMethodTable()->moduleLoaderFetch)
306 RELEASE_AND_RETURN(throwScope, globalObject->globalObjectMethodTable()->moduleLoaderFetch(globalObject, exec, this, key, parameters, scriptFetcher));
307
308 JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::tryCreate(exec, globalObject);
309 RETURN_IF_EXCEPTION(throwScope, nullptr);
310
311 auto catchScope = DECLARE_CATCH_SCOPE(vm);
312
313 String moduleKey = key.toWTFString(exec);
314 if (UNLIKELY(catchScope.exception())) {
315 JSValue exception = catchScope.exception()->value();
316 catchScope.clearException();
317 deferred->reject(exec, exception);
318 catchScope.clearException();
319 return deferred->promise();
320 }
321 deferred->reject(exec, createError(exec, makeString("Could not open the module '", moduleKey, "'.")));
322 catchScope.clearException();
323 return deferred->promise();
324}
325
326JSObject* JSModuleLoader::createImportMetaProperties(ExecState* exec, JSValue key, JSModuleRecord* moduleRecord, JSValue scriptFetcher)
327{
328 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
329 if (globalObject->globalObjectMethodTable()->moduleLoaderCreateImportMetaProperties)
330 return globalObject->globalObjectMethodTable()->moduleLoaderCreateImportMetaProperties(globalObject, exec, this, key, moduleRecord, scriptFetcher);
331 return constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
332}
333
334JSValue JSModuleLoader::evaluate(ExecState* exec, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher)
335{
336 if (Options::dumpModuleLoadingState())
337 dataLog("Loader [evaluate] ", printableModuleKey(exec, key), "\n");
338
339 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
340 if (globalObject->globalObjectMethodTable()->moduleLoaderEvaluate)
341 return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, exec, this, key, moduleRecordValue, scriptFetcher);
342
343 if (auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(exec->vm(), moduleRecordValue))
344 return moduleRecord->evaluate(exec);
345 return jsUndefined();
346}
347
348JSModuleNamespaceObject* JSModuleLoader::getModuleNamespaceObject(ExecState* exec, JSValue moduleRecordValue)
349{
350 VM& vm = exec->vm();
351 auto scope = DECLARE_THROW_SCOPE(vm);
352
353 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, moduleRecordValue);
354 if (!moduleRecord) {
355 throwTypeError(exec, scope);
356 return nullptr;
357 }
358
359 RELEASE_AND_RETURN(scope, moduleRecord->getModuleNamespace(exec));
360}
361
362// ------------------------------ Functions --------------------------------
363
364EncodedJSValue JSC_HOST_CALL moduleLoaderParseModule(ExecState* exec)
365{
366 VM& vm = exec->vm();
367 auto throwScope = DECLARE_THROW_SCOPE(vm);
368
369 JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::tryCreate(exec, exec->lexicalGlobalObject());
370 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
371
372 auto catchScope = DECLARE_CATCH_SCOPE(vm);
373 auto reject = [&] (JSValue rejectionReason) {
374 catchScope.clearException();
375 auto result = deferred->reject(exec, rejectionReason);
376 catchScope.clearException();
377 return JSValue::encode(result);
378 };
379
380 const Identifier moduleKey = exec->argument(0).toPropertyKey(exec);
381 if (UNLIKELY(catchScope.exception()))
382 return reject(catchScope.exception());
383
384 JSValue source = exec->argument(1);
385 auto* jsSourceCode = jsCast<JSSourceCode*>(source);
386 SourceCode sourceCode = jsSourceCode->sourceCode();
387
388#if ENABLE(WEBASSEMBLY)
389 if (sourceCode.provider()->sourceType() == SourceProviderSourceType::WebAssembly)
390 return JSValue::encode(WebAssemblyPrototype::instantiate(exec, deferred, moduleKey, jsSourceCode));
391#endif
392
393 CodeProfiling profile(sourceCode);
394
395 ParserError error;
396 std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
397 &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
398 JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
399 if (error.isValid())
400 return reject(error.toErrorObject(exec->lexicalGlobalObject(), sourceCode));
401 ASSERT(moduleProgramNode);
402
403 ModuleAnalyzer moduleAnalyzer(exec, moduleKey, sourceCode, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables());
404 if (UNLIKELY(catchScope.exception()))
405 return reject(catchScope.exception());
406
407 auto result = deferred->resolve(exec, moduleAnalyzer.analyze(*moduleProgramNode));
408 catchScope.clearException();
409 return JSValue::encode(result);
410}
411
412EncodedJSValue JSC_HOST_CALL moduleLoaderRequestedModules(ExecState* exec)
413{
414 VM& vm = exec->vm();
415 auto scope = DECLARE_THROW_SCOPE(vm);
416 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0));
417 if (!moduleRecord)
418 RELEASE_AND_RETURN(scope, JSValue::encode(constructEmptyArray(exec, nullptr)));
419
420 JSArray* result = constructEmptyArray(exec, nullptr, moduleRecord->requestedModules().size());
421 RETURN_IF_EXCEPTION(scope, encodedJSValue());
422 size_t i = 0;
423 for (auto& key : moduleRecord->requestedModules()) {
424 result->putDirectIndex(exec, i++, jsString(exec, key.get()));
425 RETURN_IF_EXCEPTION(scope, encodedJSValue());
426 }
427 return JSValue::encode(result);
428}
429
430EncodedJSValue JSC_HOST_CALL moduleLoaderModuleDeclarationInstantiation(ExecState* exec)
431{
432 VM& vm = exec->vm();
433 auto scope = DECLARE_THROW_SCOPE(vm);
434 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0));
435 if (!moduleRecord)
436 return JSValue::encode(jsUndefined());
437
438 if (Options::dumpModuleLoadingState())
439 dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n");
440
441 moduleRecord->link(exec, exec->argument(1));
442 RETURN_IF_EXCEPTION(scope, encodedJSValue());
443
444 return JSValue::encode(jsUndefined());
445}
446
447// ------------------------------ Hook Functions ---------------------------
448
449EncodedJSValue JSC_HOST_CALL moduleLoaderResolve(ExecState* exec)
450{
451 VM& vm = exec->vm();
452 // Hook point, Loader.resolve.
453 // https://whatwg.github.io/loader/#browser-resolve
454 // Take the name and resolve it to the unique identifier for the resource location.
455 // For example, take the "jquery" and return the URL for the resource.
456 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
457 if (!loader)
458 return JSValue::encode(jsUndefined());
459 return JSValue::encode(loader->resolve(exec, exec->argument(0), exec->argument(1), exec->argument(2)));
460}
461
462EncodedJSValue JSC_HOST_CALL moduleLoaderResolveSync(ExecState* exec)
463{
464 VM& vm = exec->vm();
465 auto scope = DECLARE_THROW_SCOPE(vm);
466
467 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
468 if (!loader)
469 return JSValue::encode(jsUndefined());
470 auto result = loader->resolveSync(exec, exec->argument(0), exec->argument(1), exec->argument(2));
471 RETURN_IF_EXCEPTION(scope, encodedJSValue());
472 return JSValue::encode(identifierToJSValue(vm, result));
473}
474
475EncodedJSValue JSC_HOST_CALL moduleLoaderFetch(ExecState* exec)
476{
477 VM& vm = exec->vm();
478 // Hook point, Loader.fetch
479 // https://whatwg.github.io/loader/#browser-fetch
480 // Take the key and fetch the resource actually.
481 // For example, JavaScriptCore shell can provide the hook fetching the resource
482 // from the local file system.
483 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
484 if (!loader)
485 return JSValue::encode(jsUndefined());
486 return JSValue::encode(loader->fetch(exec, exec->argument(0), exec->argument(1), exec->argument(2)));
487}
488
489EncodedJSValue JSC_HOST_CALL moduleLoaderGetModuleNamespaceObject(ExecState* exec)
490{
491 VM& vm = exec->vm();
492 auto scope = DECLARE_THROW_SCOPE(vm);
493
494 auto* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
495 if (!loader)
496 return JSValue::encode(jsUndefined());
497 auto* moduleNamespaceObject = loader->getModuleNamespaceObject(exec, exec->argument(0));
498 RETURN_IF_EXCEPTION(scope, encodedJSValue());
499 return JSValue::encode(moduleNamespaceObject);
500}
501
502// ------------------- Additional Hook Functions ---------------------------
503
504EncodedJSValue JSC_HOST_CALL moduleLoaderEvaluate(ExecState* exec)
505{
506 // To instrument and retrieve the errors raised from the module execution,
507 // we inserted the hook point here.
508
509 VM& vm = exec->vm();
510 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
511 if (!loader)
512 return JSValue::encode(jsUndefined());
513 return JSValue::encode(loader->evaluate(exec, exec->argument(0), exec->argument(1), exec->argument(2)));
514}
515
516} // namespace JSC
517