Files
tubestation/js/public/EnvironmentChain.h
Jan de Mooij 33eb26d6d2 Bug 1914895 - Make Symbol.unscopables support optional for non-syntactic with-environments. r=arai
In D220213 we tried to change `Symbol.unscopables` so that it's only supported on
syntactic `with` environments (for performance reasons). This failed some WPT tests
for event handlers because they use non-syntactic with-environments but have to
support `Symbol.unscopables`.

This patch adds a `JS::EnvironmentChain` class and uses it instead of an object vector
for some JS APIs. This class also lets the embedder specify whether `Symbol.unscopables`
must be supported. The `evaluate` shell function now has an option for this too.

Differential Revision: https://phabricator.services.mozilla.com/D226139
2024-10-21 17:56:43 +00:00

68 lines
2.3 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef js_EnvironmentChain_h
#define js_EnvironmentChain_h
#include "mozilla/Attributes.h" // MOZ_RAII
#include <stddef.h> // size_t
#include "jstypes.h" // JS_PUBLIC_API
#include "js/GCVector.h" // JS::RootedVector
struct JS_PUBLIC_API JSContext;
class JS_PUBLIC_API JSObject;
namespace JS {
enum class SupportUnscopables : bool { No = false, Yes = true };
/**
* JS::EnvironmentChain stores a list of objects to put on the environment
* chain.
*
* Internally the engine will create a non-syntactic 'with' environment for each
* of these objects. Note that 'with' environments aren't optimized well so you
* should use this class only if you really have to.
*
* The SupportUnscopables enum class controls whether these non-syntactic 'with'
* environments support Symbol.unscopables similar to syntactic 'with'
* statements in JS.
*
* Passing SupportUnscopables::No is better for performance because it lets us
* skip the Symbol.unscopables property lookup. Some Web APIs require supporting
* Symbol.unscopables though. In Firefox, SupportUnscopables::Yes is used for
* event handlers.
*/
class MOZ_RAII JS_PUBLIC_API EnvironmentChain {
JS::RootedObjectVector chain_;
SupportUnscopables supportUnscopables_;
public:
EnvironmentChain(JSContext* cx, SupportUnscopables supportUnscopables)
: chain_(cx), supportUnscopables_(supportUnscopables) {}
EnvironmentChain(const EnvironmentChain&) = delete;
void operator=(const EnvironmentChain&) = delete;
[[nodiscard]] bool append(JSObject* obj) { return chain_.append(obj); }
bool empty() const { return chain_.empty(); }
size_t length() const { return chain_.length(); }
RootedObjectVector& chain() { return chain_; }
const RootedObjectVector& chain() const { return chain_; }
void setSupportUnscopables(SupportUnscopables supportUnscopables) {
supportUnscopables_ = supportUnscopables;
}
SupportUnscopables supportUnscopables() const { return supportUnscopables_; }
};
} // namespace JS
#endif /* js_EnvironmentChain_h */