summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2021-02-09 03:30:21 +0000
committerPhilip Chimento <philip.chimento@gmail.com>2021-02-09 03:30:21 +0000
commit4724542ea4450254c7b3e9780ca54005759c9ef4 (patch)
treeda61b898711a8105accedba6dd011ff3b1fdf716
parente7718e64052fb3ec94166f43db2c8707fba55e25 (diff)
parenta9e1b16bfa34003fadeb23e1ea590b3f7a57b53e (diff)
downloadgjs-4724542ea4450254c7b3e9780ca54005759c9ef4.tar.gz
Merge branch 'january-maintenance' into 'master'
January maintenance See merge request GNOME/gjs!562
-rw-r--r--.eslintrc.yml6
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--doc/Package/Specification.md3
-rw-r--r--gi/function.cpp55
-rw-r--r--gjs/jsapi-class.h266
-rw-r--r--installed-tests/debugger/backtrace.debugger4
-rw-r--r--installed-tests/debugger/backtrace.debugger.js10
-rw-r--r--installed-tests/debugger/backtrace.debugger.output15
-rw-r--r--installed-tests/js/testFormat.js1
-rw-r--r--meson.build1
-rw-r--r--modules/script/_bootstrap/debugger.js12
-rw-r--r--modules/script/package.js1
12 files changed, 78 insertions, 297 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 0a07f205..0aa6acf2 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -124,6 +124,12 @@ rules:
no-restricted-globals: [error, window]
no-restricted-properties:
- error
+ - object: imports
+ property: format
+ message: Use template strings
+ - object: pkg
+ property: initFormat
+ message: Use template strings
- object: Lang
property: copyProperties
message: Use Object.assign()
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ed4d55be..65751b20 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -279,6 +279,7 @@ sanitizer_clang:
CC: clang
CXX: clang++
CONFIG_OPTS: -Db_sanitize=address,undefined -Db_lundef=false
+ TEST_OPTS: --timeout-multiplier=2
when: manual
except:
- schedules
diff --git a/doc/Package/Specification.md b/doc/Package/Specification.md
index 41aac732..ec02a688 100644
--- a/doc/Package/Specification.md
+++ b/doc/Package/Specification.md
@@ -96,7 +96,6 @@ The following API will be available to applications, through the [`package.js`](
* `pkg.prefix`, `pkg.datadir`, `pkg.libdir` will return the installed locations of those folders
* `pkg.pkgdatadir`, `pkg.moduledir`, `pkg.pkglibdir`, `pkg.localedir` will return the respective directories, or the appropriate subdirectory of the current directory if running uninstalled
* `pkg.initGettext()` will initialize gettext. After calling `globalThis._`, `globalThis.C_` and `globalThis.N_` will be available
-* `pkg.initFormat()` will initialize the format module. After calling, String.prototype.format will be available
* `pkg.initSubmodule(name)` will initialize a submodule named @name. It must be called before accessing the typelibs installed by that submodule
* `pkg.loadResource(name)` will load and register a GResource named @name. @name is optional and defaults to ${package-name}
-* `pkg.require(deps)` will mark a set of dependencies on GI and standard JS modules. **@deps** is a object whose keys are repository names and whose values are API versions. If the dependencies are not satisfied, `pkg.require()` will print an error message and quit. \ No newline at end of file
+* `pkg.require(deps)` will mark a set of dependencies on GI and standard JS modules. **@deps** is a object whose keys are repository names and whose values are API versions. If the dependencies are not satisfied, `pkg.require()` will print an error message and quit.
diff --git a/gi/function.cpp b/gi/function.cpp
index 0ef9bff1..76f2781a 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -150,7 +150,7 @@ class Function : public CWrapper<Function> {
GJS_JSAPI_RETURN_CONVENTION
static JSObject* create(JSContext* cx, GType gtype, GICallableInfo* info);
- [[nodiscard]] char* format_name();
+ [[nodiscard]] std::string format_name();
GJS_JSAPI_RETURN_CONVENTION
bool invoke(JSContext* cx, const JS::CallArgs& args,
@@ -740,14 +740,19 @@ bool GjsCallbackTrampoline::initialize(JSContext* cx,
return true;
}
-/* Intended for error messages. Return value must be freed */
-char* Function::format_name() {
- if (g_callable_info_is_method(m_info))
- return g_strdup_printf(
- "method %s.%s.%s", m_info.ns(),
- g_base_info_get_name(g_base_info_get_container(m_info)),
- m_info.name());
- return g_strdup_printf("function %s.%s", m_info.ns(), m_info.name());
+// Intended for error messages
+std::string Function::format_name() {
+ bool is_method = g_callable_info_is_method(m_info);
+ std::string retval = is_method ? "method" : "function";
+ retval += ' ';
+ retval += m_info.ns();
+ retval += '.';
+ if (is_method) {
+ retval += g_base_info_get_name(g_base_info_get_container(m_info));
+ retval += '.';
+ }
+ retval += m_info.name();
+ return retval;
}
void gjs_function_clear_async_closures() { completed_trampolines.clear(); }
@@ -814,8 +819,8 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
GjsFunctionCallState state(context, m_info);
if (state.gi_argc > GjsArgumentCache::MAX_ARGS) {
- GjsAutoChar name = format_name();
- gjs_throw(context, "Function %s has too many arguments", name.get());
+ gjs_throw(context, "Function %s has too many arguments",
+ format_name().c_str());
return false;
}
@@ -826,16 +831,13 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
// PARAM_SKIPPED args).
// args.length() is the number of arguments that were actually passed.
if (args.length() > m_js_in_argc) {
- GjsAutoChar name = format_name();
-
if (!JS::WarnUTF8(context,
"Too many arguments to %s: expected %u, got %u",
- name.get(), m_js_in_argc, args.length()))
+ format_name().c_str(), m_js_in_argc, args.length()))
return false;
} else if (args.length() < m_js_in_argc) {
- GjsAutoChar name = format_name();
-
- args.reportMoreArgsNeeded(context, name, m_js_in_argc, args.length());
+ args.reportMoreArgsNeeded(context, format_name().c_str(), m_js_in_argc,
+ args.length());
return false;
}
@@ -905,11 +907,10 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
if (!cache->marshallers->in) {
gjs_throw(context,
- "Error invoking %s.%s: impossible to determine what "
- "to pass to the '%s' argument. It may be that the "
- "function is unsupported, or there may be a bug in "
- "its annotations.",
- m_info.ns(), m_info.name(), cache->arg_name);
+ "Error invoking %s: impossible to determine what to pass "
+ "to the '%s' argument. It may be that the function is "
+ "unsupported, or there may be a bug in its annotations.",
+ format_name().c_str(), cache->arg_name);
state.failed = true;
break;
}
@@ -1174,13 +1175,13 @@ bool Function::to_string_impl(JSContext* cx, JS::MutableHandleValue rval) {
GjsAutoChar descr;
if (g_base_info_get_type(m_info) == GI_INFO_TYPE_FUNCTION) {
descr = g_strdup_printf(
- "function %s(%s) {\n\t/* wrapper for native symbol %s(); */\n}",
- m_info.name(), arg_names.c_str(),
+ "%s(%s) {\n\t/* wrapper for native symbol %s() */\n}",
+ format_name().c_str(), arg_names.c_str(),
g_function_info_get_symbol(m_info));
} else {
- descr = g_strdup_printf(
- "function %s(%s) {\n\t/* wrapper for native symbol */\n}",
- m_info.name(), arg_names.c_str());
+ descr =
+ g_strdup_printf("%s(%s) {\n\t/* wrapper for native symbol */\n}",
+ format_name().c_str(), arg_names.c_str());
}
return gjs_string_from_utf8(cx, descr, rval);
diff --git a/gjs/jsapi-class.h b/gjs/jsapi-class.h
index 5fb3961c..3d75fc1a 100644
--- a/gjs/jsapi-class.h
+++ b/gjs/jsapi-class.h
@@ -44,272 +44,6 @@ bool gjs_define_property_dynamic(JSContext *cx,
JS::HandleValue private_slot,
unsigned flags);
-/*
- * Helper methods to access private data:
- *
- * do_base_typecheck: checks that object has the right JSClass, and possibly
- * throw a TypeError exception if the check fails
- * priv_from_js: accesses the object private field; as a debug measure,
- * it also checks that the object is of a compatible
- * JSClass, but it doesn't raise an exception (it
- * wouldn't be of much use, if subsequent code crashes on
- * NULL)
- * priv_from_js_with_typecheck: a convenience function to call
- * do_base_typecheck and priv_from_js
- */
-#define GJS_DEFINE_PRIV_FROM_JS(type, klass) \
- [[nodiscard]] [[maybe_unused]] GJS_ALWAYS_INLINE static inline bool \
- do_base_typecheck(JSContext* cx, JS::HandleObject obj, bool throw_error) { \
- return gjs_typecheck_instance(cx, obj, &klass, throw_error); \
- } \
- [[nodiscard]] GJS_ALWAYS_INLINE static inline type* priv_from_js( \
- JSContext* cx, JS::HandleObject obj) { \
- return static_cast<type*>( \
- JS_GetInstancePrivate(cx, obj, &klass, nullptr)); \
- } \
- [[nodiscard]] [[maybe_unused]] static bool priv_from_js_with_typecheck( \
- JSContext* cx, JS::HandleObject obj, type** out) { \
- if (!do_base_typecheck(cx, obj, false)) \
- return false; \
- *out = priv_from_js(cx, obj); \
- return true; \
- }
-
-/*
- * GJS_GET_PRIV:
- * @cx: JSContext pointer passed into JSNative function
- * @argc: Number of arguments passed into JSNative function
- * @vp: Argument value array passed into JSNative function
- * @args: Name for JS::CallArgs variable defined by this code snippet
- * @to: Name for JS::RootedObject variable referring to function's this
- * @type: Type of private data
- * @priv: Name for private data variable defined by this code snippet
- *
- * A convenience macro for getting the private data from GJS classes using
- * priv_from_js().
- * Throws an error if the 'this' object is not the right type.
- * Use in any JSNative function.
- */
-#define GJS_GET_PRIV(cx, argc, vp, args, to, type, priv) \
- GJS_GET_THIS(cx, argc, vp, args, to); \
- if (!do_base_typecheck(cx, to, true)) \
- return false; \
- type *priv = priv_from_js(cx, to)
-
-/* Helper for GJS_DEFINE_PROTO_* macros with no parent */
-static inline JSObject* gjs_no_parent_get_proto(JSContext*) { return nullptr; }
-
-/**
- * GJS_DEFINE_PROTO:
- * @tn: The name of the prototype, as a string
- * @cn: The name of the prototype, separated by _
- * @flags: additional JSClass flags, such as JSCLASS_BACKGROUND_FINALIZE
- *
- * A convenience macro for prototype implementations.
- */
-#define GJS_DEFINE_PROTO(tn, cn, flags) \
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cn); \
-_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, G_TYPE_NONE, flags)
-
-/**
- * GJS_DEFINE_PROTO_ABSTRACT:
- * @tn: The name of the prototype, as a string
- * @cn: The name of the prototype, separated by _
- *
- * A convenience macro for prototype implementations.
- * Similar to GJS_DEFINE_PROTO but marks the prototype as abstract,
- * you won't be able to instantiate it using the new keyword
- */
-#define GJS_DEFINE_PROTO_ABSTRACT(tn, cn, flags) \
-_GJS_DEFINE_PROTO_FULL(tn, cn, no_parent, nullptr, G_TYPE_NONE, \
- flags)
-
-#define GJS_DEFINE_PROTO_WITH_GTYPE(tn, cn, gtype, flags) \
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cn); \
-_GJS_DEFINE_PROTO_FULL(tn, cn, no_parent, gjs_##cn##_constructor, \
- gtype, flags)
-
-#define GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE(tn, cn, gtype, flags) \
-_GJS_DEFINE_PROTO_FULL(tn, cn, no_parent, nullptr, gtype, flags)
-
-#define GJS_DEFINE_PROTO_WITH_PARENT(tn, cn, parent_cn, flags) \
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cn); \
-_GJS_DEFINE_PROTO_FULL(tn, cn, parent_cn, gjs_##cn##_constructor, \
- G_TYPE_NONE, flags)
-
-#define GJS_DEFINE_PROTO_ABSTRACT_WITH_PARENT(tn, cn, parent_cn, flags) \
-_GJS_DEFINE_PROTO_FULL(tn, cn, parent_cn, nullptr, G_TYPE_NONE, flags)
-
-// clang-format off
-#define _GJS_DEFINE_PROTO_FULL(type_name, cname, parent_cname, ctor, gtype, \
- jsclass_flags) \
- extern JSPropertySpec gjs_##cname##_proto_props[]; \
- extern JSFunctionSpec gjs_##cname##_proto_funcs[]; \
- extern JSFunctionSpec gjs_##cname##_static_funcs[]; \
- static void gjs_##cname##_finalize(JSFreeOp* fop, JSObject* obj); \
- static const struct JSClassOps gjs_##cname##_class_ops = { \
- nullptr, /* addProperty */ \
- nullptr, /* deleteProperty */ \
- nullptr, /* enumerate */ \
- nullptr, /* newEnumerate */ \
- nullptr, /* resolve */ \
- nullptr, /* mayResolve */ \
- gjs_##cname##_finalize \
- }; \
- static struct JSClass gjs_##cname##_class = { \
- type_name, \
- JSCLASS_HAS_PRIVATE | jsclass_flags, \
- &gjs_##cname##_class_ops \
- }; \
- [[maybe_unused]] [[nodiscard]] _GJS_DEFINE_GET_PROTO(cname) \
- [[maybe_unused]] GJS_JSAPI_RETURN_CONVENTION _GJS_DEFINE_DEFINE_PROTO(cname, parent_cname, ctor, gtype)
-// clang-format on
-
-#define GJS_DEFINE_PROTO_FUNCS_WITH_PARENT(cname, parent_cname) \
- [[maybe_unused]] [[nodiscard]] static _GJS_DEFINE_GET_PROTO(cname); \
- [[maybe_unused]] GJS_JSAPI_RETURN_CONVENTION static _GJS_DEFINE_DEFINE_PROTO( \
- cname, parent_cname, gjs_##cname##_constructor, G_TYPE_NONE);
-
-#define GJS_DEFINE_PROTO_FUNCS(cname) \
-GJS_DEFINE_PROTO_FUNCS_WITH_PARENT(cname, no_parent)
-
-#define _GJS_DEFINE_GET_PROTO(cname) \
- JSObject* gjs_##cname##_get_proto(JSContext* cx) { \
- JSObject* global = JS::CurrentGlobalOrNull(cx); \
- g_assert(global); \
- \
- JSAutoRealm ar(cx, global); \
- JS::RootedValue v_proto( \
- cx, \
- gjs_get_global_slot(global, GjsGlobalSlot::PROTOTYPE_##cname)); \
- g_assert(((void)"gjs_" #cname "_define_proto() must be called before " \
- "gjs_" #cname "_get_proto()", \
- !v_proto.isUndefined())); \
- g_assert(((void)"Someone stored some weird value in a global slot", \
- v_proto.isObject())); \
- return &v_proto.toObject(); \
- }
-
-#define _GJS_DEFINE_DEFINE_PROTO(cname, parent_cname, ctor, type) \
- bool gjs_##cname##_define_proto(JSContext* cx, JS::HandleObject module, \
- JS::MutableHandleObject proto) { \
- /* If we've been here more than once, we already have the proto */ \
- JSObject* global = JS::CurrentGlobalOrNull(cx); \
- g_assert(global); \
- \
- JSAutoRealm ar(cx, global); \
- JS::RootedValue v_proto( \
- cx, \
- gjs_get_global_slot(global, GjsGlobalSlot::PROTOTYPE_##cname)); \
- \
- if (!v_proto.isUndefined()) { \
- g_assert( \
- ((void)"Someone stored some weird value in a global slot", \
- v_proto.isObject())); \
- proto.set(&v_proto.toObject()); \
- return true; \
- } \
- \
- /* If module is not given, we are defining a global class */ \
- JS::RootedObject in_obj(cx, module); \
- if (!in_obj) \
- in_obj = global; \
- \
- /* Create the class, prototype, and constructor */ \
- JS::RootedObject parent_proto(cx, gjs_##parent_cname##_get_proto(cx)); \
- proto.set(JS_InitClass(cx, in_obj, parent_proto, &gjs_##cname##_class, \
- ctor, 0, gjs_##cname##_proto_props, \
- gjs_##cname##_proto_funcs, nullptr, \
- gjs_##cname##_static_funcs)); \
- if (!proto) \
- return false; \
- gjs_set_global_slot(global, GjsGlobalSlot::PROTOTYPE_##cname, \
- JS::ObjectValue(*proto)); \
- \
- /* Look up the constructor */ \
- JS::RootedObject ctor_obj(cx); \
- JS::RootedId class_name( \
- cx, gjs_intern_string_to_id(cx, gjs_##cname##_class.name)); \
- if (class_name == JSID_VOID) \
- return false; \
- if (!gjs_object_require_property(cx, in_obj, #cname " constructor", \
- class_name, &ctor_obj)) \
- return false; \
- \
- /* JS_InitClass defines the constructor as a property on the given \
- * "global" object. If it's a module and not the real global object, \
- * redefine it with different flags so it's enumerable; cairo copies \
- * properties from cairoNative, for example */ \
- if (module) { \
- if (!JS_DefinePropertyById(cx, module, class_name, ctor_obj, \
- GJS_MODULE_PROP_FLAGS)) \
- return false; \
- } \
- \
- /* Define the GType value as a "$gtype" property on the constructor */ \
- if (type != G_TYPE_NONE) { \
- if (!gjs_wrapper_define_gtype_prop(cx, ctor_obj, type)) \
- return false; \
- } \
- gjs_debug(GJS_DEBUG_CONTEXT, "Initialized class %s prototype %p", \
- gjs_##cname##_class.name, proto.get()); \
- return true; \
- }
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_DECLARE:
- * Prototype a constructor.
- */
-#define GJS_NATIVE_CONSTRUCTOR_DECLARE(name) \
- GJS_JSAPI_RETURN_CONVENTION static bool gjs_##name##_constructor( \
- JSContext* context, unsigned argc, JS::Value* vp)
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_VARIABLES:
- * Declare variables necessary for the constructor; should
- * be at the very top.
- */
-#define GJS_NATIVE_CONSTRUCTOR_VARIABLES(name) \
- JS::RootedObject object(context); \
- [[maybe_unused]] JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_PRELUDE:
- * Call after the initial variable declaration.
- */
-#define GJS_NATIVE_CONSTRUCTOR_PRELUDE(name) \
-{ \
- if (!argv.isConstructing()) { \
- gjs_throw_constructor_error(context); \
- return false; \
- } \
- object = JS_NewObjectForConstructor(context, &gjs_##name##_class, argv); \
- if (!object) \
- return false; \
-}
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_FINISH:
- * Call this at the end of a constructor when it's completed
- * successfully.
- */
-#define GJS_NATIVE_CONSTRUCTOR_FINISH(name) \
- argv.rval().setObject(*object);
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT:
- * Defines a constructor whose only purpose is to throw an error
- * and fail. To be used with classes that require a constructor (because they have
- * instances), but whose constructor cannot be used from JS code.
- */
-#define GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(name) \
- GJS_NATIVE_CONSTRUCTOR_DECLARE(name) \
- { \
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
- gjs_throw_abstract_constructor_error(context, args); \
- return false; \
- }
-
[[nodiscard]] JS::Value gjs_dynamic_property_private_slot(
JSObject* accessor_obj);
diff --git a/installed-tests/debugger/backtrace.debugger b/installed-tests/debugger/backtrace.debugger
index 261d388a..6f9d9516 100644
--- a/installed-tests/debugger/backtrace.debugger
+++ b/installed-tests/debugger/backtrace.debugger
@@ -7,4 +7,8 @@ c
backtrace full
bt full
where
+c
+# test printing locals when exception is thrown before initialization of a value
+c
+bt full
q
diff --git a/installed-tests/debugger/backtrace.debugger.js b/installed-tests/debugger/backtrace.debugger.js
index 9b84935b..7816d4d9 100644
--- a/installed-tests/debugger/backtrace.debugger.js
+++ b/installed-tests/debugger/backtrace.debugger.js
@@ -1,10 +1,16 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2018 Philip Chimento <philip.chimento@gmail.com>
debugger;
-[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]].forEach(array => {
+[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]].every(array => {
debugger;
- array.forEach(num => {
+ array.every(num => {
debugger;
print(num);
+ return false;
});
+ return false;
});
+function mistake(array) {
+ let {uninitialized_} = array.shift();
+}
+mistake([]);
diff --git a/installed-tests/debugger/backtrace.debugger.output b/installed-tests/debugger/backtrace.debugger.output
index f5353e29..a74e0b06 100644
--- a/installed-tests/debugger/backtrace.debugger.output
+++ b/installed-tests/debugger/backtrace.debugger.output
@@ -22,5 +22,20 @@ array = [object Array]
db> where
#0 <anonymous>([object Array], 0, [object Array]) at backtrace.debugger.js:5:4
#1 toplevel at backtrace.debugger.js:4:36
+db> c
+Debugger statement, <anonymous>(1, 0, [object Array]) at backtrace.debugger.js:7:8
+db> # test printing locals when exception is thrown before initialization of a value
+db> c
+1
+Unwinding due to exception. (Type 'c' to continue unwinding.)
+#0 mistake([object Array]) at backtrace.debugger.js:14:33
+ 14 let {uninitialized_} = array.shift();
+Exception value is:
+$1 = [object Error]
+TypeError: array.shift() is undefined
+db> bt full
+#0 mistake([object Array]) at backtrace.debugger.js:14:33
+uninitialized_ = <uninitialized>
+#1 toplevel at backtrace.debugger.js:16:7
db> q
Program exited with code 0
diff --git a/installed-tests/js/testFormat.js b/installed-tests/js/testFormat.js
index 6e46e420..c8f4fc07 100644
--- a/installed-tests/js/testFormat.js
+++ b/installed-tests/js/testFormat.js
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2013 Red Hat, Inc.
+// eslint-disable-next-line no-restricted-properties
const Format = imports.format;
String.prototype.format = Format.format;
diff --git a/meson.build b/meson.build
index 23e6ae76..a828a24f 100644
--- a/meson.build
+++ b/meson.build
@@ -113,6 +113,7 @@ endif
### Check for required libraries ###############################################
+# Note: Notify GNOME release team when adding or updating dependencies
glib_required_version = '>= 2.66.0'
glib = dependency('glib-2.0', version: glib_required_version,
fallback: ['glib', 'libglib_dep'])
diff --git a/modules/script/_bootstrap/debugger.js b/modules/script/_bootstrap/debugger.js
index d1b22ed9..0cffe703 100644
--- a/modules/script/_bootstrap/debugger.js
+++ b/modules/script/_bootstrap/debugger.js
@@ -48,6 +48,18 @@ function summarizeObject(dv) {
}
function debuggeeValueToString(dv, style = {pretty: options.pretty}) {
+ // Special sentinel values returned by Debugger.Environment.getVariable()
+ if (typeof dv === 'object' && dv !== null) {
+ if (dv.missingArguments)
+ return ['<missing>', undefined];
+ if (dv.optimizedOut)
+ return ['<optimized out>', undefined];
+ if (dv.uninitialized)
+ return ['<uninitialized>', undefined];
+ if (!(dv instanceof Debugger.Object))
+ return ['<unexpected object>', JSON.stringify(dv, null, 4)];
+ }
+
const dvrepr = dvToString(dv);
if (!style.pretty || dv === null || typeof dv !== 'object')
return [dvrepr, undefined];
diff --git a/modules/script/package.js b/modules/script/package.js
index 28cfe542..11465997 100644
--- a/modules/script/package.js
+++ b/modules/script/package.js
@@ -306,6 +306,7 @@ function initGettext() {
}
function initFormat() {
+ // eslint-disable-next-line no-restricted-properties
let format = imports.format;
String.prototype.format = format.format;
}