зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1681664 - Allow Top-level await modules which fail to evaluate due to user action to fail without crashing. r=jonco,mconley
Differential Revision: https://phabricator.services.mozilla.com/D99809
This commit is contained in:
Родитель
44d4f310aa
Коммит
0ff486bf16
|
@ -3037,7 +3037,13 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||||
JS::Rooted<JS::Value> rval(cx);
|
JS::Rooted<JS::Value> rval(cx);
|
||||||
|
|
||||||
rv = nsJSUtils::ModuleEvaluate(cx, module, &rval);
|
rv = nsJSUtils::ModuleEvaluate(cx, module, &rval);
|
||||||
MOZ_ASSERT(NS_FAILED(rv) == aes.HasException());
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// If we have an infinite loop in a module, which is stopped by the
|
||||||
|
// user, the module evaluation will fail, but we will not have an
|
||||||
|
// AutoEntryScript exception.
|
||||||
|
MOZ_ASSERT(!aes.HasException());
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest));
|
LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest));
|
||||||
|
@ -3052,14 +3058,22 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Path for when Top Level Await is enabled
|
// Path for when Top Level Await is enabled
|
||||||
JS::Rooted<JSObject*> aEvaluationPromise(cx, &rval.toObject());
|
JS::Rooted<JSObject*> aEvaluationPromise(cx);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// If the user cancels the evaluation on an infinite loop, we need
|
||||||
|
// to skip this step. In that case, ModuleEvaluate will not return a
|
||||||
|
// promise, rval will be undefined. We should treat it as a failed
|
||||||
|
// evaluation, and reject appropriately.
|
||||||
|
aEvaluationPromise.set(&rval.toObject());
|
||||||
|
}
|
||||||
if (request->IsDynamicImport()) {
|
if (request->IsDynamicImport()) {
|
||||||
FinishDynamicImport(cx, request, rv, aEvaluationPromise);
|
FinishDynamicImport(cx, request, rv, aEvaluationPromise);
|
||||||
} else {
|
} else {
|
||||||
// If this is not a dynamic import, and if the promise is rejected,
|
// If this is not a dynamic import, and if the promise is rejected,
|
||||||
// the value is unwrapped from the promise value.
|
// the value is unwrapped from the promise value.
|
||||||
if (!JS::ThrowOnModuleEvaluationFailure(cx, aEvaluationPromise)) {
|
if (!JS::ThrowOnModuleEvaluationFailure(cx, aEvaluationPromise)) {
|
||||||
LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest));
|
LOG(("ScriptLoadRequest (%p): evaluation failed on throw",
|
||||||
|
aRequest));
|
||||||
// For a dynamic import, the promise is rejected. Otherwise an
|
// For a dynamic import, the promise is rejected. Otherwise an
|
||||||
// error is either reported by AutoEntryScript.
|
// error is either reported by AutoEntryScript.
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
while (true) {};
|
|
@ -38,9 +38,11 @@ support-files =
|
||||||
test2_bug629331.html
|
test2_bug629331.html
|
||||||
finalizationRegistry_worker.js
|
finalizationRegistry_worker.js
|
||||||
private_field_worker.js
|
private_field_worker.js
|
||||||
|
bug1681664_helper.js
|
||||||
prefs =
|
prefs =
|
||||||
javascript.options.weakrefs=true
|
javascript.options.weakrefs=true
|
||||||
javascript.options.experimental.private_fields=true
|
javascript.options.experimental.private_fields=true
|
||||||
|
javascript.options.experimental.top_level_await=true
|
||||||
|
|
||||||
[test_bug384632.html]
|
[test_bug384632.html]
|
||||||
[test_bug390488.html]
|
[test_bug390488.html]
|
||||||
|
@ -99,6 +101,7 @@ skip-if = toolkit == "android" && debug && !is_fennec
|
||||||
[test_bug1094930.html]
|
[test_bug1094930.html]
|
||||||
[test_bug1158558.html]
|
[test_bug1158558.html]
|
||||||
[test_bug1448048.html]
|
[test_bug1448048.html]
|
||||||
|
[test_bug1681664.html]
|
||||||
[test_crosscompartment_weakmap.html]
|
[test_crosscompartment_weakmap.html]
|
||||||
[test_enable_privilege.html]
|
[test_enable_privilege.html]
|
||||||
[test_frameWrapping.html]
|
[test_frameWrapping.html]
|
||||||
|
@ -123,4 +126,4 @@ skip-if = (debug == false)
|
||||||
[test_weakRefs_cross_compartment.html]
|
[test_weakRefs_cross_compartment.html]
|
||||||
[test_weakRefs_collected_wrapper.html]
|
[test_weakRefs_collected_wrapper.html]
|
||||||
[test_private_field_dom.html]
|
[test_private_field_dom.html]
|
||||||
[test_private_field_worker.html]
|
[test_private_field_worker.html]
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<title>Test page for bug 1681664</title>
|
||||||
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
<script>
|
||||||
|
SimpleTest.waitForExplicitFinish()
|
||||||
|
async function init() {
|
||||||
|
var Services = SpecialPowers.Services;
|
||||||
|
var observer = {
|
||||||
|
observe(subject, topic, data) {
|
||||||
|
if (topic === "process-hang-report") {
|
||||||
|
var report = subject.QueryInterface(Ci.nsIHangReport);
|
||||||
|
report.terminateScript();
|
||||||
|
Services.obs.removeObserver(observer, "process-hang-report");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.obs.addObserver(observer, "process-hang-report");
|
||||||
|
try {
|
||||||
|
await import("test_bug1681664.js");
|
||||||
|
result.textContent = "FAIL";
|
||||||
|
} catch (ex) {
|
||||||
|
result.textContent = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="result"></p>
|
||||||
|
<script>
|
||||||
|
(async function() {
|
||||||
|
await init();
|
||||||
|
is(result.textContent, "PASS", "Infinite loop script should not cause browser crash");
|
||||||
|
SimpleTest.finish()
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче