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