Lines 35-40
a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec1
|
35 |
#include "JSExecState.h" |
35 |
#include "JSExecState.h" |
36 |
#include "JSPaintWorkletGlobalScope.h" |
36 |
#include "JSPaintWorkletGlobalScope.h" |
37 |
#include "JSServiceWorkerGlobalScope.h" |
37 |
#include "JSServiceWorkerGlobalScope.h" |
|
|
38 |
#include "LoadableModuleScript.h" |
39 |
#include "ModuleFetchFailureKind.h" |
40 |
#include "ModuleFetchParameters.h" |
38 |
#include "ScriptSourceCode.h" |
41 |
#include "ScriptSourceCode.h" |
39 |
#include "WebCoreJSClientData.h" |
42 |
#include "WebCoreJSClientData.h" |
40 |
#include "WorkerConsoleClient.h" |
43 |
#include "WorkerConsoleClient.h" |
Lines 43-49
a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec2
|
43 |
#include <JavaScriptCore/Exception.h> |
46 |
#include <JavaScriptCore/Exception.h> |
44 |
#include <JavaScriptCore/ExceptionHelpers.h> |
47 |
#include <JavaScriptCore/ExceptionHelpers.h> |
45 |
#include <JavaScriptCore/GCActivityCallback.h> |
48 |
#include <JavaScriptCore/GCActivityCallback.h> |
|
|
49 |
#include <JavaScriptCore/JSInternalPromise.h> |
46 |
#include <JavaScriptCore/JSLock.h> |
50 |
#include <JavaScriptCore/JSLock.h> |
|
|
51 |
#include <JavaScriptCore/JSNativeStdFunction.h> |
52 |
#include <JavaScriptCore/JSScriptFetchParameters.h> |
53 |
#include <JavaScriptCore/JSScriptFetcher.h> |
47 |
#include <JavaScriptCore/StrongInlines.h> |
54 |
#include <JavaScriptCore/StrongInlines.h> |
48 |
|
55 |
|
49 |
namespace WebCore { |
56 |
namespace WebCore { |
Lines 228-234
void WorkerOrWorkletScriptController::evaluate(const ScriptSourceCode& sourceCod
a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec3
|
228 |
} |
235 |
} |
229 |
} |
236 |
} |
230 |
|
237 |
|
231 |
template<typename JSGlobalScopePrototype, typename JSGlobalScope, typename GlobalScope> |
238 |
static Identifier jsValueToModuleKey(JSGlobalObject* lexicalGlobalObject, JSValue value) |
|
|
239 |
{ |
240 |
if (value.isSymbol()) |
241 |
return Identifier::fromUid(jsCast<Symbol*>(value)->privateName()); |
242 |
ASSERT(value.isString()); |
243 |
return asString(value)->toIdentifier(lexicalGlobalObject); |
244 |
} |
245 |
|
246 |
MessageQueueWaitResult WorkerOrWorkletScriptController::loadModuleSynchronously(LoadableModuleScript& moduleScript, const ScriptSourceCode& sourceCode) |
247 |
{ |
248 |
if (isExecutionForbidden()) |
249 |
return MessageQueueTerminated; |
250 |
|
251 |
initScriptIfNeeded(); |
252 |
|
253 |
auto& globalObject = *m_globalScopeWrapper.get(); |
254 |
VM& vm = globalObject.vm(); |
255 |
JSLockHolder lock { vm }; |
256 |
|
257 |
auto& promise = JSExecState::loadModule(globalObject, sourceCode.jsSourceCode(), JSC::JSScriptFetcher::create(vm, { &moduleScript })); |
258 |
|
259 |
RefPtr<LoadableModuleScript> moduleScriptRef(&moduleScript); |
260 |
|
261 |
auto& fulfillHandler = *JSNativeStdFunction::create(vm, &globalObject, 1, String(), [moduleScriptRef](JSGlobalObject* globalObject, CallFrame* callFrame) -> JSC::EncodedJSValue { |
262 |
VM& vm = globalObject->vm(); |
263 |
auto scope = DECLARE_THROW_SCOPE(vm); |
264 |
Identifier moduleKey = jsValueToModuleKey(globalObject, callFrame->argument(0)); |
265 |
RETURN_IF_EXCEPTION(scope, { }); |
266 |
moduleScriptRef->notifyLoadCompleted(*moduleKey.impl()); |
267 |
return JSValue::encode(jsUndefined()); |
268 |
}); |
269 |
|
270 |
auto& rejectHandler = *JSNativeStdFunction::create(vm, &globalObject, 1, String(), [moduleScriptRef](JSGlobalObject* globalObject, CallFrame* callFrame) { |
271 |
VM& vm = globalObject->vm(); |
272 |
JSValue errorValue = callFrame->argument(0); |
273 |
if (errorValue.isObject()) { |
274 |
auto* object = JSC::asObject(errorValue); |
275 |
if (JSValue failureKindValue = object->getDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName())) { |
276 |
// This is host propagated error in the module loader pipeline. |
277 |
switch (static_cast<ModuleFetchFailureKind>(failureKindValue.asInt32())) { |
278 |
case ModuleFetchFailureKind::WasErrored: |
279 |
moduleScriptRef->notifyLoadFailed(LoadableScript::Error { |
280 |
LoadableScript::ErrorType::CachedScript, |
281 |
WTF::nullopt |
282 |
}); |
283 |
break; |
284 |
case ModuleFetchFailureKind::WasCanceled: |
285 |
moduleScriptRef->notifyLoadWasCanceled(); |
286 |
break; |
287 |
} |
288 |
return JSValue::encode(jsUndefined()); |
289 |
} |
290 |
} |
291 |
|
292 |
auto scope = DECLARE_CATCH_SCOPE(vm); |
293 |
moduleScriptRef->notifyLoadFailed(LoadableScript::Error { |
294 |
LoadableScript::ErrorType::CachedScript, |
295 |
LoadableScript::ConsoleMessage { |
296 |
MessageSource::JS, |
297 |
MessageLevel::Error, |
298 |
retrieveErrorMessage(*globalObject, vm, errorValue, scope), |
299 |
} |
300 |
}); |
301 |
return JSValue::encode(jsUndefined()); |
302 |
}); |
303 |
|
304 |
promise.then(&globalObject, &fulfillHandler, &rejectHandler); |
305 |
|
306 |
// Drive RunLoop until we get either of "Worker is terminated", "Loading is done", or "Loading is failed". |
307 |
WorkerRunLoop& runLoop = m_globalScope->workerOrWorkletThread()->runLoop(); |
308 |
String mode = makeString("loadModuleSynchronously", runLoop.createUniqueId()); |
309 |
|
310 |
MessageQueueWaitResult result = MessageQueueMessageReceived; |
311 |
while ((!moduleScriptRef->isLoaded() || !moduleScriptRef->wasCanceled()) && result != MessageQueueTerminated) |
312 |
result = runLoop.runInMode(m_globalScope, mode); |
313 |
|
314 |
// FIXME: Currently we are not offering cancelling. |
315 |
// if (!loader->done() && result == MessageQueueTerminated) |
316 |
// loader->cancel(); |
317 |
|
318 |
return result; |
319 |
} |
320 |
|
321 |
void WorkerOrWorkletScriptController::linkAndEvaluateModule(LoadableModuleScript& moduleScript, const ScriptSourceCode& sourceCode, String* returnedExceptionMessage) |
322 |
{ |
323 |
if (isExecutionForbidden()) |
324 |
return; |
325 |
|
326 |
initScriptIfNeeded(); |
327 |
|
328 |
auto& globalObject = *m_globalScopeWrapper.get(); |
329 |
VM& vm = globalObject.vm(); |
330 |
JSLockHolder lock { vm }; |
331 |
|
332 |
NakedPtr<JSC::Exception> returnedException; |
333 |
JSExecState::linkAndEvaluateModule(globalObject, Identifier::fromUid(vm, moduleScript.moduleKey()), jsUndefined(), returnedException); |
334 |
if ((returnedException && isTerminatedExecutionException(vm, returnedException)) || isTerminatingExecution()) { |
335 |
forbidExecution(); |
336 |
return; |
337 |
} |
338 |
|
339 |
if (returnedException) { |
340 |
if (m_globalScope->canIncludeErrorDetails(sourceCode.cachedScript(), sourceCode.url().string())) { |
341 |
// FIXME: It's not great that this can run arbitrary code to string-ify the value of the exception. |
342 |
// Do we need to do anything to handle that properly, if it, say, raises another exception? |
343 |
if (returnedExceptionMessage) |
344 |
*returnedExceptionMessage = returnedException->value().toWTFString(&globalObject); |
345 |
} else { |
346 |
// Overwrite the detailed error with a generic error. |
347 |
String genericErrorMessage { "Script error."_s }; |
348 |
if (returnedExceptionMessage) |
349 |
*returnedExceptionMessage = genericErrorMessage; |
350 |
returnedException = JSC::Exception::create(vm, createError(&globalObject, genericErrorMessage)); |
351 |
} |
352 |
} |
353 |
} |
354 |
|
355 |
template<typename JSGlobalScopePrototype, typename JSGlobalScope, typename GlobalScope> |
232 |
void WorkerOrWorkletScriptController::initScriptWithSubclass() |
356 |
void WorkerOrWorkletScriptController::initScriptWithSubclass() |
233 |
{ |
357 |
{ |
234 |
ASSERT(!m_globalScopeWrapper); |
358 |
ASSERT(!m_globalScopeWrapper); |