commit b46ba4b78eb9ff83adf03bbf09e8c45f058d55ba
parent 4cd49eb13b7db4af87558f8eeefd025c40063369
Author: Bryan Thrall <bthrall@mozilla.com>
Date: Wed, 12 Nov 2025 22:02:50 +0000
Bug 1989115 - Track unsafe call with ABI state in release r=mgaudet,rhunt
Differential Revision: https://phabricator.services.mozilla.com/D268761
Diffstat:
4 files changed, 8 insertions(+), 29 deletions(-)
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
@@ -4885,7 +4885,6 @@ void MacroAssembler::setupAlignedABICall() {
dynamicAlignment_ = false;
}
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
void MacroAssembler::wasmCheckUnsafeCallWithABIPre() {
// Set the JSContext::inUnsafeCallWithABI flag.
loadPtr(Address(InstanceReg, wasm::Instance::offsetOfCx()),
@@ -4895,6 +4894,7 @@ void MacroAssembler::wasmCheckUnsafeCallWithABIPre() {
store32(Imm32(1), flagAddr);
}
+#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
void MacroAssembler::wasmCheckUnsafeCallWithABIPost() {
// Check JSContext::inUnsafeCallWithABI was cleared as expected.
Label ok;
@@ -4986,7 +4986,6 @@ void MacroAssembler::callWithABINoProfiler(void* fun, ABIType result,
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
if (check == CheckUnsafeCallWithABI::Check) {
// Set the JSContext::inUnsafeCallWithABI flag.
push(ReturnReg);
@@ -4997,7 +4996,6 @@ void MacroAssembler::callWithABINoProfiler(void* fun, ABIType result,
// On arm64, SP may be < PSP now (that's OK).
// eg testcase: tests/bug1375074.js
}
-#endif
call(ImmPtr(fun));
@@ -5029,13 +5027,9 @@ CodeOffset MacroAssembler::callWithABI(wasm::BytecodeOffset bytecode,
// The instance register is used in builtin thunks and must be set.
bool needsBuiltinThunk = wasm::NeedsBuiltinThunk(imm);
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
// The builtin thunk exits the JIT activation, if we don't have one we must
// use AutoUnsafeCallWithABI inside the builtin and check that here.
bool checkUnsafeCallWithABI = !needsBuiltinThunk;
-#else
- bool checkUnsafeCallWithABI = false;
-#endif
if (needsBuiltinThunk || checkUnsafeCallWithABI) {
if (instanceOffset) {
loadPtr(Address(getStackPointer(), *instanceOffset + stackAdjust),
@@ -5045,11 +5039,9 @@ CodeOffset MacroAssembler::callWithABI(wasm::BytecodeOffset bytecode,
}
}
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
if (checkUnsafeCallWithABI) {
wasmCheckUnsafeCallWithABIPre();
}
-#endif
CodeOffset raOffset = call(
wasm::CallSiteDesc(bytecode.offset(), wasm::CallSiteKind::Symbolic), imm);
@@ -6398,14 +6390,12 @@ CodeOffset MacroAssembler::wasmCallBuiltinInstanceMethod(
MOZ_CRASH("Unknown abi passing style for pointer");
}
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
// The builtin thunk exits the JIT activation, if we don't have one we must
// use AutoUnsafeCallWithABI inside the builtin and check that here.
bool checkUnsafeCallWithABI = !wasm::NeedsBuiltinThunk(builtin);
if (checkUnsafeCallWithABI) {
wasmCheckUnsafeCallWithABIPre();
}
-#endif
CodeOffset ret = call(desc, builtin);
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
@@ -838,9 +838,9 @@ class MacroAssembler : public MacroAssemblerSpecific {
void callWithABIPost(uint32_t stackAdjust, ABIType result,
bool callFromWasm = false) PER_ARCH;
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
// Set the JSContext::inUnsafeCallWithABI flag using InstanceReg.
void wasmCheckUnsafeCallWithABIPre();
+#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
// Check JSContext::inUnsafeCallWithABI was cleared as expected.
void wasmCheckUnsafeCallWithABIPost();
#endif
diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp
@@ -1218,10 +1218,8 @@ JSContext::JSContext(JSRuntime* runtime, const JS::ContextOptions& options)
activation_(this, nullptr),
profilingActivation_(nullptr),
noExecuteDebuggerTop(this, nullptr),
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
inUnsafeCallWithABI(this, false),
hasAutoUnsafeCallWithABI(this, false),
-#endif
#ifdef DEBUG
liveArraySortDataInstances(this, 0),
#endif
@@ -1703,8 +1701,6 @@ void JSContext::suspendExecutionTracing() {
#endif
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
-
AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness)
: cx_(TlsContext.get()),
nested_(cx_ ? cx_->hasAutoUnsafeCallWithABI : false),
@@ -1713,6 +1709,7 @@ AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness)
// This is a helper thread doing Ion or Wasm compilation - nothing to do.
return;
}
+#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
switch (strictness) {
case UnsafeABIStrictness::NoExceptions:
MOZ_ASSERT(!JS_IsExceptionPending(cx_));
@@ -1725,6 +1722,7 @@ AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness)
checkForPendingException_ = false;
break;
}
+#endif
cx_->hasAutoUnsafeCallWithABI = true;
}
@@ -1733,16 +1731,16 @@ AutoUnsafeCallWithABI::~AutoUnsafeCallWithABI() {
if (!cx_) {
return;
}
+#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
MOZ_ASSERT(cx_->hasAutoUnsafeCallWithABI);
+ MOZ_ASSERT_IF(checkForPendingException_, !JS_IsExceptionPending(cx_));
+#endif
if (!nested_) {
cx_->hasAutoUnsafeCallWithABI = false;
cx_->inUnsafeCallWithABI = false;
}
- MOZ_ASSERT_IF(checkForPendingException_, !JS_IsExceptionPending(cx_));
}
-#endif // JS_CHECK_UNSAFE_CALL_WITH_ABI
-
#ifdef __wasi__
JS_PUBLIC_API void js::IncWasiRecursionDepth(JSContext* cx) {
++JS::RootingContext::get(cx)->wasiRecursionDepth;
diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h
@@ -458,11 +458,9 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
return offsetof(JSContext, jitActivation);
}
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
static size_t offsetOfInUnsafeCallWithABI() {
return offsetof(JSContext, inUnsafeCallWithABI);
}
-#endif
public:
js::InterpreterStack& interpreterStack() {
@@ -501,10 +499,8 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
*/
js::ContextData<js::EnterDebuggeeNoExecute*> noExecuteDebuggerTop;
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
js::ContextData<uint32_t> inUnsafeCallWithABI;
js::ContextData<bool> hasAutoUnsafeCallWithABI;
-#endif
#ifdef DEBUG
js::ContextData<uint32_t> liveArraySortDataInstances;
@@ -1222,22 +1218,17 @@ enum UnsafeABIStrictness {
// the function is not called with a pending exception, and that it does not
// throw an exception itself.
class MOZ_RAII AutoUnsafeCallWithABI {
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
JSContext* cx_;
bool nested_;
+#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
bool checkForPendingException_;
#endif
JS::AutoCheckCannotGC nogc;
public:
-#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI
explicit AutoUnsafeCallWithABI(
UnsafeABIStrictness strictness = UnsafeABIStrictness::NoExceptions);
~AutoUnsafeCallWithABI();
-#else
- explicit AutoUnsafeCallWithABI(
- UnsafeABIStrictness unused_ = UnsafeABIStrictness::NoExceptions) {}
-#endif
};
template <typename T>