JSModuleLoader.cpp
1 /* 2 * Copyright (C) 2015-2019 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 "JSCInlines.h" 33 #include "JSInternalPromise.h" 34 #include "JSMap.h" 35 #include "JSModuleNamespaceObject.h" 36 #include "JSModuleRecord.h" 37 #include "JSSourceCode.h" 38 #include "JSWebAssembly.h" 39 #include "ModuleAnalyzer.h" 40 #include "Nodes.h" 41 #include "ObjectConstructor.h" 42 #include "Parser.h" 43 #include "ParserError.h" 44 45 namespace JSC { 46 47 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderParseModule); 48 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderRequestedModules); 49 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderEvaluate); 50 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderModuleDeclarationInstantiation); 51 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderResolve); 52 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderResolveSync); 53 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderFetch); 54 static JSC_DECLARE_HOST_FUNCTION(moduleLoaderGetModuleNamespaceObject); 55 56 } 57 58 #include "JSModuleLoader.lut.h" 59 60 namespace JSC { 61 62 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSModuleLoader); 63 64 const ClassInfo JSModuleLoader::s_info = { "ModuleLoader", &Base::s_info, &moduleLoaderTable, nullptr, CREATE_METHOD_TABLE(JSModuleLoader) }; 65 66 /* Source for JSModuleLoader.lut.h 67 @begin moduleLoaderTable 68 ensureRegistered JSBuiltin DontEnum|Function 1 69 forceFulfillPromise JSBuiltin DontEnum|Function 2 70 fulfillFetch JSBuiltin DontEnum|Function 2 71 requestFetch JSBuiltin DontEnum|Function 3 72 requestInstantiate JSBuiltin DontEnum|Function 3 73 requestSatisfy JSBuiltin DontEnum|Function 3 74 link JSBuiltin DontEnum|Function 2 75 moduleDeclarationInstantiation moduleLoaderModuleDeclarationInstantiation DontEnum|Function 2 76 moduleEvaluation JSBuiltin DontEnum|Function 2 77 evaluate moduleLoaderEvaluate DontEnum|Function 3 78 provideFetch JSBuiltin DontEnum|Function 2 79 loadAndEvaluateModule JSBuiltin DontEnum|Function 3 80 loadModule JSBuiltin DontEnum|Function 3 81 linkAndEvaluateModule JSBuiltin DontEnum|Function 2 82 requestImportModule JSBuiltin DontEnum|Function 3 83 dependencyKeysIfEvaluated JSBuiltin DontEnum|Function 1 84 getModuleNamespaceObject moduleLoaderGetModuleNamespaceObject DontEnum|Function 1 85 parseModule moduleLoaderParseModule DontEnum|Function 2 86 requestedModules moduleLoaderRequestedModules DontEnum|Function 1 87 resolve moduleLoaderResolve DontEnum|Function 2 88 resolveSync moduleLoaderResolveSync DontEnum|Function 2 89 fetch moduleLoaderFetch DontEnum|Function 3 90 @end 91 */ 92 93 JSModuleLoader::JSModuleLoader(VM& vm, Structure* structure) 94 : JSNonFinalObject(vm, structure) 95 { 96 } 97 98 void JSModuleLoader::finishCreation(JSGlobalObject* globalObject, VM& vm) 99 { 100 auto scope = DECLARE_CATCH_SCOPE(vm); 101 102 Base::finishCreation(vm); 103 ASSERT(inherits(vm, info())); 104 JSMap* map = JSMap::create(globalObject, vm, globalObject->mapStructure()); 105 scope.releaseAssertNoException(); 106 putDirect(vm, Identifier::fromString(vm, "registry"), map); 107 } 108 109 // ------------------------------ Functions -------------------------------- 110 111 static String printableModuleKey(JSGlobalObject* globalObject, JSValue key) 112 { 113 VM& vm = globalObject->vm(); 114 auto scope = DECLARE_CATCH_SCOPE(vm); 115 if (key.isString() || key.isSymbol()) { 116 auto propertyName = key.toPropertyKey(globalObject); 117 scope.assertNoException(); // This is OK since this function is just for debugging purpose. 118 return propertyName.impl(); 119 } 120 return vm.propertyNames->emptyIdentifier.impl(); 121 } 122 123 static JSInternalPromise* reject(JSGlobalObject* globalObject, CatchScope& catchScope, JSInternalPromise* promise) 124 { 125 VM& vm = globalObject->vm(); 126 Exception* exception = catchScope.exception(); 127 ASSERT(exception); 128 if (UNLIKELY(isTerminatedExecutionException(vm, exception))) 129 return promise; 130 catchScope.clearException(); 131 promise->reject(globalObject, exception->value()); 132 return promise; 133 } 134 135 JSArray* JSModuleLoader::dependencyKeysIfEvaluated(JSGlobalObject* globalObject, JSValue key) 136 { 137 VM& vm = globalObject->vm(); 138 auto scope = DECLARE_THROW_SCOPE(vm); 139 140 JSObject* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().dependencyKeysIfEvaluatedPublicName())); 141 RETURN_IF_EXCEPTION(scope, nullptr); 142 auto callData = JSC::getCallData(vm, function); 143 ASSERT(callData.type != CallData::Type::None); 144 145 MarkedArgumentBuffer arguments; 146 arguments.append(key); 147 148 JSValue result = call(globalObject, function, callData, this, arguments); 149 RETURN_IF_EXCEPTION(scope, nullptr); 150 151 return jsDynamicCast<JSArray*>(vm, result); 152 } 153 154 JSValue JSModuleLoader::provideFetch(JSGlobalObject* globalObject, JSValue key, const SourceCode& sourceCode) 155 { 156 VM& vm = globalObject->vm(); 157 auto scope = DECLARE_THROW_SCOPE(vm); 158 159 JSObject* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().provideFetchPublicName())); 160 RETURN_IF_EXCEPTION(scope, { }); 161 auto callData = JSC::getCallData(vm, function); 162 ASSERT(callData.type != CallData::Type::None); 163 164 SourceCode source { sourceCode }; 165 MarkedArgumentBuffer arguments; 166 arguments.append(key); 167 arguments.append(JSSourceCode::create(vm, WTFMove(source))); 168 ASSERT(!arguments.hasOverflowed()); 169 170 RELEASE_AND_RETURN(scope, call(globalObject, function, callData, this, arguments)); 171 } 172 173 JSInternalPromise* JSModuleLoader::loadAndEvaluateModule(JSGlobalObject* globalObject, JSValue moduleName, JSValue parameters, JSValue scriptFetcher) 174 { 175 VM& vm = globalObject->vm(); 176 auto scope = DECLARE_THROW_SCOPE(vm); 177 178 JSObject* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().loadAndEvaluateModulePublicName())); 179 RETURN_IF_EXCEPTION(scope, nullptr); 180 auto callData = JSC::getCallData(vm, function); 181 ASSERT(callData.type != CallData::Type::None); 182 183 MarkedArgumentBuffer arguments; 184 arguments.append(moduleName); 185 arguments.append(parameters); 186 arguments.append(scriptFetcher); 187 ASSERT(!arguments.hasOverflowed()); 188 189 JSValue promise = call(globalObject, function, callData, this, arguments); 190 RETURN_IF_EXCEPTION(scope, nullptr); 191 return jsCast<JSInternalPromise*>(promise); 192 } 193 194 JSInternalPromise* JSModuleLoader::loadModule(JSGlobalObject* globalObject, JSValue moduleName, JSValue parameters, JSValue scriptFetcher) 195 { 196 VM& vm = globalObject->vm(); 197 auto scope = DECLARE_THROW_SCOPE(vm); 198 199 JSObject* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().loadModulePublicName())); 200 RETURN_IF_EXCEPTION(scope, nullptr); 201 auto callData = JSC::getCallData(vm, function); 202 ASSERT(callData.type != CallData::Type::None); 203 204 MarkedArgumentBuffer arguments; 205 arguments.append(moduleName); 206 arguments.append(parameters); 207 arguments.append(scriptFetcher); 208 ASSERT(!arguments.hasOverflowed()); 209 210 JSValue promise = call(globalObject, function, callData, this, arguments); 211 RETURN_IF_EXCEPTION(scope, nullptr); 212 return jsCast<JSInternalPromise*>(promise); 213 } 214 215 JSValue JSModuleLoader::linkAndEvaluateModule(JSGlobalObject* globalObject, JSValue moduleKey, JSValue scriptFetcher) 216 { 217 VM& vm = globalObject->vm(); 218 auto scope = DECLARE_THROW_SCOPE(vm); 219 220 JSObject* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().linkAndEvaluateModulePublicName())); 221 RETURN_IF_EXCEPTION(scope, { }); 222 auto callData = JSC::getCallData(vm, function); 223 ASSERT(callData.type != CallData::Type::None); 224 225 MarkedArgumentBuffer arguments; 226 arguments.append(moduleKey); 227 arguments.append(scriptFetcher); 228 ASSERT(!arguments.hasOverflowed()); 229 230 RELEASE_AND_RETURN(scope, call(globalObject, function, callData, this, arguments)); 231 } 232 233 JSInternalPromise* JSModuleLoader::requestImportModule(JSGlobalObject* globalObject, const Identifier& moduleKey, JSValue parameters, JSValue scriptFetcher) 234 { 235 VM& vm = globalObject->vm(); 236 auto scope = DECLARE_THROW_SCOPE(vm); 237 238 auto* function = jsCast<JSObject*>(get(globalObject, vm.propertyNames->builtinNames().requestImportModulePublicName())); 239 RETURN_IF_EXCEPTION(scope, nullptr); 240 auto callData = JSC::getCallData(vm, function); 241 ASSERT(callData.type != CallData::Type::None); 242 243 MarkedArgumentBuffer arguments; 244 arguments.append(jsString(vm, moduleKey.impl())); 245 arguments.append(parameters); 246 arguments.append(scriptFetcher); 247 ASSERT(!arguments.hasOverflowed()); 248 249 JSValue promise = call(globalObject, function, callData, this, arguments); 250 RETURN_IF_EXCEPTION(scope, nullptr); 251 return jsCast<JSInternalPromise*>(promise); 252 } 253 254 JSInternalPromise* JSModuleLoader::importModule(JSGlobalObject* globalObject, JSString* moduleName, JSValue parameters, const SourceOrigin& referrer) 255 { 256 dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [import] ", printableModuleKey(globalObject, moduleName)); 257 258 VM& vm = globalObject->vm(); 259 auto catchScope = DECLARE_CATCH_SCOPE(vm); 260 261 if (globalObject->globalObjectMethodTable()->moduleLoaderImportModule) 262 return globalObject->globalObjectMethodTable()->moduleLoaderImportModule(globalObject, this, moduleName, parameters, referrer); 263 264 auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); 265 String moduleNameString = moduleName->value(globalObject); 266 if (UNLIKELY(catchScope.exception())) 267 return reject(globalObject, catchScope, promise); 268 promise->reject(globalObject, createError(globalObject, makeString("Could not import the module '", moduleNameString, "'."))); 269 return promise; 270 } 271 272 Identifier JSModuleLoader::resolveSync(JSGlobalObject* globalObject, JSValue name, JSValue referrer, JSValue scriptFetcher) 273 { 274 dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [resolve] ", printableModuleKey(globalObject, name)); 275 276 if (globalObject->globalObjectMethodTable()->moduleLoaderResolve) 277 return globalObject->globalObjectMethodTable()->moduleLoaderResolve(globalObject, this, name, referrer, scriptFetcher); 278 return name.toPropertyKey(globalObject); 279 } 280 281 JSInternalPromise* JSModuleLoader::resolve(JSGlobalObject* globalObject, JSValue name, JSValue referrer, JSValue scriptFetcher) 282 { 283 VM& vm = globalObject->vm(); 284 auto catchScope = DECLARE_CATCH_SCOPE(vm); 285 286 auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); 287 const Identifier moduleKey = resolveSync(globalObject, name, referrer, scriptFetcher); 288 if (UNLIKELY(catchScope.exception())) 289 return reject(globalObject, catchScope, promise); 290 promise->resolve(globalObject, identifierToJSValue(vm, moduleKey)); 291 return promise; 292 } 293 294 JSInternalPromise* JSModuleLoader::fetch(JSGlobalObject* globalObject, JSValue key, JSValue parameters, JSValue scriptFetcher) 295 { 296 dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [fetch] ", printableModuleKey(globalObject, key)); 297 298 VM& vm = globalObject->vm(); 299 auto catchScope = DECLARE_CATCH_SCOPE(vm); 300 301 if (globalObject->globalObjectMethodTable()->moduleLoaderFetch) 302 return globalObject->globalObjectMethodTable()->moduleLoaderFetch(globalObject, this, key, parameters, scriptFetcher); 303 304 auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); 305 String moduleKey = key.toWTFString(globalObject); 306 if (UNLIKELY(catchScope.exception())) 307 return reject(globalObject, catchScope, promise); 308 promise->reject(globalObject, createError(globalObject, makeString("Could not open the module '", moduleKey, "'."))); 309 return promise; 310 } 311 312 JSObject* JSModuleLoader::createImportMetaProperties(JSGlobalObject* globalObject, JSValue key, JSModuleRecord* moduleRecord, JSValue scriptFetcher) 313 { 314 if (globalObject->globalObjectMethodTable()->moduleLoaderCreateImportMetaProperties) 315 return globalObject->globalObjectMethodTable()->moduleLoaderCreateImportMetaProperties(globalObject, this, key, moduleRecord, scriptFetcher); 316 return constructEmptyObject(globalObject->vm(), globalObject->nullPrototypeObjectStructure()); 317 } 318 319 JSValue JSModuleLoader::evaluate(JSGlobalObject* globalObject, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher) 320 { 321 dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [evaluate] ", printableModuleKey(globalObject, key)); 322 323 if (globalObject->globalObjectMethodTable()->moduleLoaderEvaluate) 324 return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, this, key, moduleRecordValue, scriptFetcher); 325 326 return evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher); 327 } 328 329 JSValue JSModuleLoader::evaluateNonVirtual(JSGlobalObject* globalObject, JSValue, JSValue moduleRecordValue, JSValue) 330 { 331 if (auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(globalObject->vm(), moduleRecordValue)) 332 return moduleRecord->evaluate(globalObject); 333 return jsUndefined(); 334 } 335 336 JSModuleNamespaceObject* JSModuleLoader::getModuleNamespaceObject(JSGlobalObject* globalObject, JSValue moduleRecordValue) 337 { 338 VM& vm = globalObject->vm(); 339 auto scope = DECLARE_THROW_SCOPE(vm); 340 341 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, moduleRecordValue); 342 if (!moduleRecord) { 343 throwTypeError(globalObject, scope); 344 return nullptr; 345 } 346 347 RELEASE_AND_RETURN(scope, moduleRecord->getModuleNamespace(globalObject)); 348 } 349 350 // ------------------------------ Functions -------------------------------- 351 352 JSC_DEFINE_HOST_FUNCTION(moduleLoaderParseModule, (JSGlobalObject* globalObject, CallFrame* callFrame)) 353 { 354 VM& vm = globalObject->vm(); 355 356 auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); 357 358 auto catchScope = DECLARE_CATCH_SCOPE(vm); 359 360 auto rejectWithError = [&](JSValue error) { 361 promise->reject(globalObject, error); 362 return promise; 363 }; 364 365 const Identifier moduleKey = callFrame->argument(0).toPropertyKey(globalObject); 366 if (UNLIKELY(catchScope.exception())) 367 return JSValue::encode(reject(globalObject, catchScope, promise)); 368 369 JSValue source = callFrame->argument(1); 370 auto* jsSourceCode = jsCast<JSSourceCode*>(source); 371 SourceCode sourceCode = jsSourceCode->sourceCode(); 372 373 #if ENABLE(WEBASSEMBLY) 374 if (sourceCode.provider()->sourceType() == SourceProviderSourceType::WebAssembly) 375 return JSValue::encode(JSWebAssembly::instantiate(globalObject, promise, moduleKey, jsSourceCode)); 376 #endif 377 378 ParserError error; 379 std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>( 380 vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin, 381 JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error); 382 if (error.isValid()) 383 return JSValue::encode(rejectWithError(error.toErrorObject(globalObject, sourceCode))); 384 ASSERT(moduleProgramNode); 385 386 ModuleAnalyzer moduleAnalyzer(globalObject, moduleKey, sourceCode, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables()); 387 if (UNLIKELY(catchScope.exception())) 388 return JSValue::encode(reject(globalObject, catchScope, promise)); 389 390 promise->resolve(globalObject, moduleAnalyzer.analyze(*moduleProgramNode)); 391 catchScope.clearException(); 392 return JSValue::encode(promise); 393 } 394 395 JSC_DEFINE_HOST_FUNCTION(moduleLoaderRequestedModules, (JSGlobalObject* globalObject, CallFrame* callFrame)) 396 { 397 VM& vm = globalObject->vm(); 398 auto scope = DECLARE_THROW_SCOPE(vm); 399 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, callFrame->argument(0)); 400 if (!moduleRecord) 401 RELEASE_AND_RETURN(scope, JSValue::encode(constructEmptyArray(globalObject, nullptr))); 402 403 JSArray* result = constructEmptyArray(globalObject, nullptr, moduleRecord->requestedModules().size()); 404 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 405 size_t i = 0; 406 for (auto& key : moduleRecord->requestedModules()) { 407 result->putDirectIndex(globalObject, i++, jsString(vm, key.get())); 408 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 409 } 410 return JSValue::encode(result); 411 } 412 413 JSC_DEFINE_HOST_FUNCTION(moduleLoaderModuleDeclarationInstantiation, (JSGlobalObject* globalObject, CallFrame* callFrame)) 414 { 415 VM& vm = globalObject->vm(); 416 auto scope = DECLARE_THROW_SCOPE(vm); 417 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, callFrame->argument(0)); 418 if (!moduleRecord) 419 return JSValue::encode(jsUndefined()); 420 421 dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [link] ", moduleRecord->moduleKey()); 422 423 moduleRecord->link(globalObject, callFrame->argument(1)); 424 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 425 426 return JSValue::encode(jsUndefined()); 427 } 428 429 // ------------------------------ Hook Functions --------------------------- 430 431 JSC_DEFINE_HOST_FUNCTION(moduleLoaderResolve, (JSGlobalObject* globalObject, CallFrame* callFrame)) 432 { 433 VM& vm = globalObject->vm(); 434 // Hook point, Loader.resolve. 435 // https://whatwg.github.io/loader/#browser-resolve 436 // Take the name and resolve it to the unique identifier for the resource location. 437 // For example, take the "jquery" and return the URL for the resource. 438 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue()); 439 if (!loader) 440 return JSValue::encode(jsUndefined()); 441 return JSValue::encode(loader->resolve(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2))); 442 } 443 444 JSC_DEFINE_HOST_FUNCTION(moduleLoaderResolveSync, (JSGlobalObject* globalObject, CallFrame* callFrame)) 445 { 446 VM& vm = globalObject->vm(); 447 auto scope = DECLARE_THROW_SCOPE(vm); 448 449 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue()); 450 if (!loader) 451 return JSValue::encode(jsUndefined()); 452 auto result = loader->resolveSync(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2)); 453 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 454 return JSValue::encode(identifierToJSValue(vm, result)); 455 } 456 457 JSC_DEFINE_HOST_FUNCTION(moduleLoaderFetch, (JSGlobalObject* globalObject, CallFrame* callFrame)) 458 { 459 VM& vm = globalObject->vm(); 460 // Hook point, Loader.fetch 461 // https://whatwg.github.io/loader/#browser-fetch 462 // Take the key and fetch the resource actually. 463 // For example, JavaScriptCore shell can provide the hook fetching the resource 464 // from the local file system. 465 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue()); 466 if (!loader) 467 return JSValue::encode(jsUndefined()); 468 return JSValue::encode(loader->fetch(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2))); 469 } 470 471 JSC_DEFINE_HOST_FUNCTION(moduleLoaderGetModuleNamespaceObject, (JSGlobalObject* globalObject, CallFrame* callFrame)) 472 { 473 VM& vm = globalObject->vm(); 474 auto scope = DECLARE_THROW_SCOPE(vm); 475 476 auto* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue()); 477 if (!loader) 478 return JSValue::encode(jsUndefined()); 479 auto* moduleNamespaceObject = loader->getModuleNamespaceObject(globalObject, callFrame->argument(0)); 480 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 481 return JSValue::encode(moduleNamespaceObject); 482 } 483 484 // ------------------- Additional Hook Functions --------------------------- 485 486 JSC_DEFINE_HOST_FUNCTION(moduleLoaderEvaluate, (JSGlobalObject* globalObject, CallFrame* callFrame)) 487 { 488 // To instrument and retrieve the errors raised from the module execution, 489 // we inserted the hook point here. 490 491 VM& vm = globalObject->vm(); 492 JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue()); 493 if (!loader) 494 return JSValue::encode(jsUndefined()); 495 return JSValue::encode(loader->evaluate(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2))); 496 } 497 498 } // namespace JSC