Skip to content

Commit 894b8f9

Browse files
3v1n0mtwebster
authored andcommitted
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.
1 parent 5f00667 commit 894b8f9

4 files changed

Lines changed: 33 additions & 18 deletions

File tree

cjs/deprecation.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ struct hash<DeprecationEntry> {
8181
static std::unordered_set<DeprecationEntry> logged_messages;
8282

8383
GJS_JSAPI_RETURN_CONVENTION
84-
static JS::UniqueChars get_callsite(JSContext* cx) {
84+
static JS::UniqueChars get_callsite(JSContext* cx, unsigned max_frames) {
8585
JS::RootedObject stack_frame(cx);
8686
if (!JS::CaptureCurrentStack(cx, &stack_frame,
87-
JS::StackCapture(JS::MaxFrames(1))) ||
87+
JS::StackCapture(JS::MaxFrames(max_frames))) ||
8888
!stack_frame)
8989
return nullptr;
9090

@@ -98,8 +98,9 @@ static JS::UniqueChars get_callsite(JSContext* cx) {
9898

9999
static void warn_deprecated_unsafe_internal(JSContext* cx,
100100
const GjsDeprecationMessageId id,
101-
const char* msg) {
102-
JS::UniqueChars callsite(get_callsite(cx));
101+
const char* msg,
102+
unsigned max_frames) {
103+
JS::UniqueChars callsite(get_callsite(cx, max_frames));
103104
DeprecationEntry entry(id, callsite.get());
104105
if (!logged_messages.count(entry)) {
105106
JS::UniqueChars stack_dump =
@@ -113,13 +114,15 @@ static void warn_deprecated_unsafe_internal(JSContext* cx,
113114
* stack dump API and not the "safe" gjs_dumpstack() which can only print to
114115
* stdout or stderr. Do not use this function during GC, for example. */
115116
void _gjs_warn_deprecated_once_per_callsite(JSContext* cx,
116-
const GjsDeprecationMessageId id) {
117-
warn_deprecated_unsafe_internal(cx, id, messages[id]);
117+
const GjsDeprecationMessageId id,
118+
unsigned max_frames) {
119+
warn_deprecated_unsafe_internal(cx, id, messages[id], max_frames);
118120
}
119121

120122
void _gjs_warn_deprecated_once_per_callsite(
121123
JSContext* cx, GjsDeprecationMessageId id,
122-
const std::vector<const char*>& args) {
124+
const std::vector<const char*>& args,
125+
unsigned max_frames) {
123126
// In C++20, use std::format() for this
124127
std::string_view format_string{messages[id]};
125128
std::stringstream message;
@@ -149,5 +152,5 @@ void _gjs_warn_deprecated_once_per_callsite(
149152
message << format_string.substr(copied, std::string::npos);
150153

151154
std::string message_formatted = message.str();
152-
warn_deprecated_unsafe_internal(cx, id, message_formatted.c_str());
155+
warn_deprecated_unsafe_internal(cx, id, message_formatted.c_str(), max_frames);
153156
}

cjs/deprecation.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ enum GjsDeprecationMessageId : unsigned {
2121
};
2222

2323
void _gjs_warn_deprecated_once_per_callsite(JSContext* cx,
24-
GjsDeprecationMessageId message);
24+
GjsDeprecationMessageId message,
25+
unsigned max_frames = 1);
2526

2627
void _gjs_warn_deprecated_once_per_callsite(
2728
JSContext* cx, GjsDeprecationMessageId id,
28-
const std::vector<const char*>& args);
29+
const std::vector<const char*>& args, unsigned max_frames = 1);
2930

3031
#endif // GJS_DEPRECATION_H_

installed-tests/js/testGio.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -440,16 +440,22 @@ Exec=${GLib.find_program_in_path('sh')}
440440
it('can be created using Gio wrapper', function () {
441441
expectDeprecationWarning(() =>
442442
expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull());
443-
expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull();
443+
expectDeprecationWarning(() =>
444+
expect(Gio.DesktopAppInfo.new_from_keyfile(keyFile)).not.toBeNull());
444445
});
445446

446447
describe('provides platform-independent functions', function () {
447448
[Gio, GioUnix].forEach(ns => it(`when created from ${ns.__name__}`, function () {
448449
if (!requiredVersion)
449450
pending('Installed Gio is not new enough for this test');
450451

451-
const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
452-
expect(appInfo.get_name()).toBe('Some Application');
452+
const maybeExpectDeprecationWarning = ns === Gio
453+
? expectDeprecationWarning : tf => tf();
454+
455+
maybeExpectDeprecationWarning(() => {
456+
const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
457+
expect(appInfo.get_name()).toBe('Some Application');
458+
});
453459
}));
454460
});
455461

@@ -458,9 +464,14 @@ Exec=${GLib.find_program_in_path('sh')}
458464
if (!requiredVersion)
459465
pending('Installed Gio is not new enough for this test');
460466

461-
const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
462-
expect(appInfo.has_key('Name')).toBeTrue();
463-
expect(appInfo.get_string('Name')).toBe('Some Application');
467+
const maybeExpectDeprecationWarning = ns === Gio
468+
? expectDeprecationWarning : tf => tf();
469+
470+
maybeExpectDeprecationWarning(() => {
471+
const appInfo = ns.DesktopAppInfo.new_from_keyfile(keyFile);
472+
expect(appInfo.has_key('Name')).toBeTrue();
473+
expect(appInfo.get_string('Name')).toBe('Some Application');
474+
});
464475
}));
465476
});
466477
});

modules/print.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ static bool warn_deprecated_once_per_callsite(JSContext* cx, unsigned argc,
206206

207207
if (args.length() == 1) {
208208
_gjs_warn_deprecated_once_per_callsite(
209-
cx, GjsDeprecationMessageId(message_id));
209+
cx, GjsDeprecationMessageId(message_id), 2);
210210
return true;
211211
}
212212

@@ -225,7 +225,7 @@ static bool warn_deprecated_once_per_callsite(JSContext* cx, unsigned argc,
225225
}
226226

227227
_gjs_warn_deprecated_once_per_callsite(
228-
cx, GjsDeprecationMessageId(message_id), format_args);
228+
cx, GjsDeprecationMessageId(message_id), format_args, 2);
229229
return true;
230230
}
231231

0 commit comments

Comments
 (0)