1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
Date: Fri, 12 Sep 2025 00:28:09 +0200
Subject: cjs/deprecation: Use a larger deprecation stack for JS invoked
requests
When using warnDeprecatedOncePerCallsite() from JS we need to use a
larger stack to track the call site, otherwise we may end up considering
the same call site for different actual callers.
In fact when using this in Gio.js override the call site is always the
same, but we care about where that function is being invoked from.
---
cjs/deprecation.cpp | 19 +++++++++++--------
cjs/deprecation.h | 5 +++--
installed-tests/js/testGio.js | 23 +++++++++++++++++------
modules/print.cpp | 4 ++--
4 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/cjs/deprecation.cpp b/cjs/deprecation.cpp
index 9c4e44d..fca66ff 100644
--- a/cjs/deprecation.cpp
+++ b/cjs/deprecation.cpp
@@ -81,10 +81,10 @@ struct hash<DeprecationEntry> {
static std::unordered_set<DeprecationEntry> logged_messages;
GJS_JSAPI_RETURN_CONVENTION
-static JS::UniqueChars get_callsite(JSContext* cx) {
+static JS::UniqueChars get_callsite(JSContext* cx, unsigned max_frames) {
JS::RootedObject stack_frame(cx);
if (!JS::CaptureCurrentStack(cx, &stack_frame,
- JS::StackCapture(JS::MaxFrames(1))) ||
+ JS::StackCapture(JS::MaxFrames(max_frames))) ||
!stack_frame)
return nullptr;
@@ -98,8 +98,9 @@ static JS::UniqueChars get_callsite(JSContext* cx) {
static void warn_deprecated_unsafe_internal(JSContext* cx,
const GjsDeprecationMessageId id,
- const char* msg) {
- JS::UniqueChars callsite(get_callsite(cx));
+ const char* msg,
+ unsigned max_frames) {
+ JS::UniqueChars callsite(get_callsite(cx, max_frames));
DeprecationEntry entry(id, callsite.get());
if (!logged_messages.count(entry)) {
JS::UniqueChars stack_dump =
@@ -113,13 +114,15 @@ static void warn_deprecated_unsafe_internal(JSContext* cx,
* stack dump API and not the "safe" gjs_dumpstack() which can only print to
* stdout or stderr. Do not use this function during GC, for example. */
void _gjs_warn_deprecated_once_per_callsite(JSContext* cx,
- const GjsDeprecationMessageId id) {
- warn_deprecated_unsafe_internal(cx, id, messages[id]);
+ const GjsDeprecationMessageId id,
+ unsigned max_frames) {
+ warn_deprecated_unsafe_internal(cx, id, messages[id], max_frames);
}
void _gjs_warn_deprecated_once_per_callsite(
JSContext* cx, GjsDeprecationMessageId id,
- const std::vector<const char*>& args) {
+ const std::vector<const char*>& args,
+ unsigned max_frames) {
// In C++20, use std::format() for this
std::string_view format_string{messages[id]};
std::stringstream message;
@@ -149,5 +152,5 @@ void _gjs_warn_deprecated_once_per_callsite(
message << format_string.substr(copied, std::string::npos);
std::string message_formatted = message.str();
- warn_deprecated_unsafe_internal(cx, id, message_formatted.c_str());
+ warn_deprecated_unsafe_internal(cx, id, message_formatted.c_str(), max_frames);
}
diff --git a/cjs/deprecation.h b/cjs/deprecation.h
index a59613d..7a76780 100644
--- a/cjs/deprecation.h
+++ b/cjs/deprecation.h
@@ -21,10 +21,11 @@ enum GjsDeprecationMessageId : unsigned {
};
void _gjs_warn_deprecated_once_per_callsite(JSContext* cx,
- GjsDeprecationMessageId message);
+ GjsDeprecationMessageId message,
+ unsigned max_frames = 1);
void _gjs_warn_deprecated_once_per_callsite(
JSContext* cx, GjsDeprecationMessageId id,
- const std::vector<const char*>& args);
+ const std::vector<const char*>& args, unsigned max_frames = 1);
#endif // GJS_DEPRECATION_H_
diff --git a/installed-tests/js/testGio.js b/installed-tests/js/testGio.js
index f67aec4..b92d374 100644
--- a/installed-tests/js/testGio.js
+++ b/installed-tests/js/testGio.js
@@ -440,7 +440,8 @@ Exec=${GLib.find_program_in_path('sh')}
it('can be created using Gio wrapper', function () {
expectDeprecationWarning(() =>
expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull());
- expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull();
+ expectDeprecationWarning(() =>
+ expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull());
});
describe('provides platform-independent functions', function () {
@@ -448,8 +449,13 @@ Exec=${GLib.find_program_in_path('sh')}
if (!requiredVersion)
pending('Installed Gio is not new enough for this test');
- const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
- expect(appInfo.get_name()).toBe('Some Application');
+ const maybeExpectDeprecationWarning = ns === Gio
+ ? expectDeprecationWarning : tf => tf();
+
+ maybeExpectDeprecationWarning(() => {
+ const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
+ expect(appInfo.get_name()).toBe('Some Application');
+ });
}));
});
@@ -458,9 +464,14 @@ Exec=${GLib.find_program_in_path('sh')}
if (!requiredVersion)
pending('Installed Gio is not new enough for this test');
- const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
- expect(appInfo.has_key('Name')).toBeTrue();
- expect(appInfo.get_string('Name')).toBe('Some Application');
+ const maybeExpectDeprecationWarning = ns === Gio
+ ? expectDeprecationWarning : tf => tf();
+
+ maybeExpectDeprecationWarning(() => {
+ const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
+ expect(appInfo.has_key('Name')).toBeTrue();
+ expect(appInfo.get_string('Name')).toBe('Some Application');
+ });
}));
});
});
diff --git a/modules/print.cpp b/modules/print.cpp
index c6aaa26..9f029ef 100644
--- a/modules/print.cpp
+++ b/modules/print.cpp
@@ -206,7 +206,7 @@ static bool warn_deprecated_once_per_callsite(JSContext* cx, unsigned argc,
if (args.length() == 1) {
_gjs_warn_deprecated_once_per_callsite(
- cx, GjsDeprecationMessageId(message_id));
+ cx, GjsDeprecationMessageId(message_id), 2);
return true;
}
@@ -225,7 +225,7 @@ static bool warn_deprecated_once_per_callsite(JSContext* cx, unsigned argc,
}
_gjs_warn_deprecated_once_per_callsite(
- cx, GjsDeprecationMessageId(message_id), format_args);
+ cx, GjsDeprecationMessageId(message_id), format_args, 2);
return true;
}
|