commit 7031c812f30f195fa1f9936e7f6c22402b851678
parent 5fd4b324f557e098fb09367c7908037a092de1b9
Author: Ryan Hunt <rhunt@eqrion.net>
Date: Thu, 18 Dec 2025 14:55:06 +0000
Bug 2002635 - Move asm.js deprecation warning into parsing so it always fires. r=arai
Right now we only warn if we successfully compile the asm.js code. Once
we have disabled asm.js optimizations, it would still be good to warn
users that they should migrate to wasm.
Differential Revision: https://phabricator.services.mozilla.com/D275816
Diffstat:
4 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
@@ -49,8 +49,9 @@
#include "js/ErrorReport.h" // JSErrorBase
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/HashTable.h"
-#include "js/RegExpFlags.h" // JS::RegExpFlags
-#include "js/Stack.h" // JS::NativeStackLimit
+#include "js/RegExpFlags.h" // JS::RegExpFlags
+#include "js/Stack.h" // JS::NativeStackLimit
+#include "util/DifferentialTesting.h"
#include "util/StringBuilder.h" // StringBuilder
#include "vm/BytecodeUtil.h"
#include "vm/FunctionFlags.h" // js::FunctionFlags
@@ -3834,7 +3835,8 @@ static inline bool IsUseAsmDirective(const TokenPos& pos,
}
template <typename Unit>
-bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
+bool Parser<SyntaxParseHandler, Unit>::asmJS(TokenPos directivePos,
+ ListNodeType list) {
// While asm.js could technically be validated and compiled during syntax
// parsing, we have no guarantee that some later JS wouldn't abort the
// syntax parse and cause us to re-parse (and re-compile) the asm.js module.
@@ -3846,7 +3848,8 @@ bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
}
template <typename Unit>
-bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
+bool Parser<FullParseHandler, Unit>::asmJS(TokenPos directivePos,
+ ListNodeType list) {
// Disable syntax parsing in anything nested inside the asm.js module.
disableSyntaxParser();
@@ -3878,6 +3881,18 @@ bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
return false;
}
+
+ // Warn about asm.js deprecation even if we failed validation. Do this after
+ // compilation so that this warning is the last one we emit. This makes
+ // testing in asm.js/disabled-warning.js easier.
+ if (!js::SupportDifferentialTesting() &&
+ JS::Prefs::warn_asmjs_deprecation()) {
+ if (!warningAt(directivePos.begin, JSMSG_USE_ASM_DEPRECATED)) {
+ return false;
+ }
+ }
+
+ // If we failed validation, trigger a reparse. See above.
if (!validated) {
pc_->newDirectives->setAsmJS();
return false;
@@ -3887,8 +3902,9 @@ bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
}
template <class ParseHandler, typename Unit>
-inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
- return asFinalParser()->asmJS(list);
+inline bool GeneralParser<ParseHandler, Unit>::asmJS(TokenPos directivePos,
+ ListNodeType list) {
+ return asFinalParser()->asmJS(directivePos, list);
}
/*
@@ -4003,7 +4019,7 @@ bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
}
} else if (IsUseAsmDirective(directivePos, directive)) {
if (pc_->isFunctionBox()) {
- return asmJS(list);
+ return asmJS(directivePos, list);
}
return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
}
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
@@ -1529,7 +1529,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
TokenPos pos);
private:
- inline bool asmJS(ListNodeType list);
+ inline bool asmJS(TokenPos directivePos, ListNodeType list);
};
template <typename Unit>
@@ -1664,7 +1664,7 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
bool tryAnnexB);
- bool asmJS(ListNodeType list);
+ bool asmJS(TokenPos directivePos, ListNodeType list);
// Functions present only in Parser<SyntaxParseHandler, Unit>.
};
@@ -1848,7 +1848,7 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
}
- bool asmJS(ListNodeType list);
+ bool asmJS(TokenPos directivePos, ListNodeType list);
};
template <class Parser>
diff --git a/js/src/jit-test/tests/asm.js/disabled-warning.js b/js/src/jit-test/tests/asm.js/disabled-warning.js
@@ -0,0 +1,7 @@
+enableLastWarning();
+new Function(`"use asm"; return {};`);
+var warning = getLastWarning();
+assertEq(warning !== null, true, "warning should be caught");
+assertEq(warning.name, "Warning");
+assertEq(warning.lineNumber, 3);
+assertEq(warning.columnNumber, 1);
diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp
@@ -1032,15 +1032,6 @@ bool Module::instantiate(JSContext* cx, ImportValues& imports,
}
}
}
-
- // Warn if the user is using asm.js still.
- if (JS::Prefs::warn_asmjs_deprecation() && codeMeta().isAsmJS()) {
- if (!js::WarnNumberASCII(cx, JSMSG_USE_ASM_DEPRECATED)) {
- if (cx->isExceptionPending()) {
- cx->clearPendingException();
- }
- }
- }
}
if (cx->options().testWasmAwaitTier2() &&