зеркало из https://github.com/mozilla/gecko-dev.git
378 строки
12 KiB
C++
378 строки
12 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
|
* 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/. */
|
|
|
|
/*
|
|
* Options specified when creating a realm to determine its behavior, immutable
|
|
* options determining the behavior of an existing realm, and mutable options on
|
|
* an existing realm that may be changed when desired.
|
|
*/
|
|
|
|
#ifndef js_RealmOptions_h
|
|
#define js_RealmOptions_h
|
|
|
|
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
|
|
|
#include "jstypes.h" // JS_PUBLIC_API
|
|
|
|
#include "js/Class.h" // JSTraceOp
|
|
|
|
struct JS_PUBLIC_API JSContext;
|
|
class JS_PUBLIC_API JSObject;
|
|
|
|
namespace JS {
|
|
|
|
class JS_PUBLIC_API Compartment;
|
|
class JS_PUBLIC_API Realm;
|
|
class JS_PUBLIC_API Zone;
|
|
|
|
} // namespace JS
|
|
|
|
namespace JS {
|
|
|
|
/**
|
|
* Specification for which compartment/zone a newly created realm should use.
|
|
*/
|
|
enum class CompartmentSpecifier {
|
|
// Create a new realm and compartment in the single runtime wide system
|
|
// zone. The meaning of this zone is left to the embedder.
|
|
NewCompartmentInSystemZone,
|
|
|
|
// Create a new realm and compartment in a particular existing zone.
|
|
NewCompartmentInExistingZone,
|
|
|
|
// Create a new zone/compartment.
|
|
NewCompartmentAndZone,
|
|
|
|
// Create a new realm in an existing compartment.
|
|
ExistingCompartment,
|
|
};
|
|
|
|
/**
|
|
* RealmCreationOptions specifies options relevant to creating a new realm, that
|
|
* are either immutable characteristics of that realm or that are discarded
|
|
* after the realm has been created.
|
|
*
|
|
* Access to these options on an existing realm is read-only: if you need
|
|
* particular selections, you must make them before you create the realm.
|
|
*/
|
|
class JS_PUBLIC_API RealmCreationOptions {
|
|
public:
|
|
RealmCreationOptions() : comp_(nullptr) {}
|
|
|
|
JSTraceOp getTrace() const { return traceGlobal_; }
|
|
RealmCreationOptions& setTrace(JSTraceOp op) {
|
|
traceGlobal_ = op;
|
|
return *this;
|
|
}
|
|
|
|
Zone* zone() const {
|
|
MOZ_ASSERT(compSpec_ == CompartmentSpecifier::NewCompartmentInExistingZone);
|
|
return zone_;
|
|
}
|
|
Compartment* compartment() const {
|
|
MOZ_ASSERT(compSpec_ == CompartmentSpecifier::ExistingCompartment);
|
|
return comp_;
|
|
}
|
|
CompartmentSpecifier compartmentSpecifier() const { return compSpec_; }
|
|
|
|
// Set the compartment/zone to use for the realm. See CompartmentSpecifier
|
|
// above.
|
|
RealmCreationOptions& setNewCompartmentInSystemZone();
|
|
RealmCreationOptions& setNewCompartmentInExistingZone(JSObject* obj);
|
|
RealmCreationOptions& setNewCompartmentAndZone();
|
|
RealmCreationOptions& setExistingCompartment(JSObject* obj);
|
|
RealmCreationOptions& setExistingCompartment(Compartment* compartment);
|
|
|
|
// Certain compartments are implementation details of the embedding, and
|
|
// references to them should never leak out to script. This flag causes this
|
|
// realm to skip firing onNewGlobalObject and makes addDebuggee a no-op for
|
|
// this global.
|
|
//
|
|
// Debugger visibility is per-compartment, not per-realm (it's only practical
|
|
// to enforce visibility on compartment boundaries), so if a realm is being
|
|
// created in an extant compartment, its requested visibility must match that
|
|
// of the compartment.
|
|
bool invisibleToDebugger() const { return invisibleToDebugger_; }
|
|
RealmCreationOptions& setInvisibleToDebugger(bool flag) {
|
|
invisibleToDebugger_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
// Realms used for off-thread compilation have their contents merged into a
|
|
// target realm when the compilation is finished. This is only allowed if
|
|
// this flag is set. The invisibleToDebugger flag must also be set for such
|
|
// realms.
|
|
bool mergeable() const { return mergeable_; }
|
|
RealmCreationOptions& setMergeable(bool flag) {
|
|
mergeable_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
// Determines whether this realm should preserve JIT code on non-shrinking
|
|
// GCs.
|
|
bool preserveJitCode() const { return preserveJitCode_; }
|
|
RealmCreationOptions& setPreserveJitCode(bool flag) {
|
|
preserveJitCode_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool cloneSingletons() const { return cloneSingletons_; }
|
|
RealmCreationOptions& setCloneSingletons(bool flag) {
|
|
cloneSingletons_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getSharedMemoryAndAtomicsEnabled() const;
|
|
RealmCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
|
|
|
|
// When these prefs (COOP and COEP) are not enabled, shared memory objects
|
|
// (e.g. SAB) are not allowed to be postMessage()'ed. And we want to provide
|
|
// a clear warning message to users/developer so that they would have an idea
|
|
// if the implementations of the COOP and COEP headers are finished or not. So
|
|
// that they would know if they can fix the SAB by deploying the COOP and
|
|
// COEP headers or not.
|
|
bool getCoopAndCoepEnabled() const;
|
|
RealmCreationOptions& setCoopAndCoepEnabled(bool flag);
|
|
|
|
bool getStreamsEnabled() const { return streams_; }
|
|
RealmCreationOptions& setStreamsEnabled(bool flag) {
|
|
streams_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getReadableByteStreamsEnabled() const { return readableByteStreams_; }
|
|
RealmCreationOptions& setReadableByteStreamsEnabled(bool flag) {
|
|
readableByteStreams_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getBYOBStreamReadersEnabled() const { return byobStreamReaders_; }
|
|
RealmCreationOptions& setBYOBStreamReadersEnabled(bool enabled) {
|
|
byobStreamReaders_ = enabled;
|
|
return *this;
|
|
}
|
|
|
|
bool getWritableStreamsEnabled() const { return writableStreams_; }
|
|
RealmCreationOptions& setWritableStreamsEnabled(bool enabled) {
|
|
writableStreams_ = enabled;
|
|
return *this;
|
|
}
|
|
|
|
bool getReadableStreamPipeToEnabled() const { return readableStreamPipeTo_; }
|
|
RealmCreationOptions& setReadableStreamPipeToEnabled(bool enabled) {
|
|
readableStreamPipeTo_ = enabled;
|
|
return *this;
|
|
}
|
|
|
|
bool getFieldsEnabled() const { return fields_; }
|
|
RealmCreationOptions& setFieldsEnabled(bool flag) {
|
|
fields_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getAwaitFixEnabled() const { return awaitFix_; }
|
|
RealmCreationOptions& setAwaitFixEnabled(bool flag) {
|
|
awaitFix_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getWeakRefsEnabled() const { return weakRefs_; }
|
|
RealmCreationOptions& setWeakRefsEnabled(bool flag) {
|
|
weakRefs_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getToSourceEnabled() const { return toSource_; }
|
|
RealmCreationOptions& setToSourceEnabled(bool flag) {
|
|
toSource_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool getPropertyErrorMessageFixEnabled() const {
|
|
return propertyErrorMessageFix_;
|
|
}
|
|
RealmCreationOptions& setPropertyErrorMessageFixEnabled(bool flag) {
|
|
propertyErrorMessageFix_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
// This flag doesn't affect JS engine behavior. It is used by Gecko to
|
|
// mark whether content windows and workers are "Secure Context"s. See
|
|
// https://w3c.github.io/webappsec-secure-contexts/
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
|
|
bool secureContext() const { return secureContext_; }
|
|
RealmCreationOptions& setSecureContext(bool flag) {
|
|
secureContext_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
uint64_t profilerRealmID() const { return profilerRealmID_; }
|
|
RealmCreationOptions& setProfilerRealmID(uint64_t id) {
|
|
profilerRealmID_ = id;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
JSTraceOp traceGlobal_ = nullptr;
|
|
CompartmentSpecifier compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
|
|
union {
|
|
Compartment* comp_;
|
|
Zone* zone_;
|
|
};
|
|
uint64_t profilerRealmID_ = 0;
|
|
bool invisibleToDebugger_ = false;
|
|
bool mergeable_ = false;
|
|
bool preserveJitCode_ = false;
|
|
bool cloneSingletons_ = false;
|
|
bool sharedMemoryAndAtomics_ = false;
|
|
bool coopAndCoep_ = false;
|
|
bool streams_ = false;
|
|
bool readableByteStreams_ = false;
|
|
bool byobStreamReaders_ = false;
|
|
bool writableStreams_ = false;
|
|
bool readableStreamPipeTo_ = false;
|
|
bool fields_ = false;
|
|
bool awaitFix_ = false;
|
|
bool weakRefs_ = false;
|
|
bool toSource_ = false;
|
|
bool propertyErrorMessageFix_ = false;
|
|
bool secureContext_ = false;
|
|
};
|
|
|
|
/**
|
|
* RealmBehaviors specifies behaviors of a realm that can be changed after the
|
|
* realm's been created.
|
|
*/
|
|
class JS_PUBLIC_API RealmBehaviors {
|
|
public:
|
|
RealmBehaviors() = default;
|
|
|
|
// For certain globals, we know enough about the code that will run in them
|
|
// that we can discard script source entirely.
|
|
bool discardSource() const { return discardSource_; }
|
|
RealmBehaviors& setDiscardSource(bool flag) {
|
|
discardSource_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool disableLazyParsing() const { return disableLazyParsing_; }
|
|
RealmBehaviors& setDisableLazyParsing(bool flag) {
|
|
disableLazyParsing_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool deferredParserAlloc() const { return deferredParserAlloc_; }
|
|
RealmBehaviors& setDeferredParserAlloc(bool flag) {
|
|
deferredParserAlloc_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
bool clampAndJitterTime() const { return clampAndJitterTime_; }
|
|
RealmBehaviors& setClampAndJitterTime(bool flag) {
|
|
clampAndJitterTime_ = flag;
|
|
return *this;
|
|
}
|
|
|
|
class Override {
|
|
public:
|
|
Override() : mode_(Default) {}
|
|
|
|
bool get(bool defaultValue) const {
|
|
if (mode_ == Default) {
|
|
return defaultValue;
|
|
}
|
|
return mode_ == ForceTrue;
|
|
}
|
|
|
|
void set(bool overrideValue) {
|
|
mode_ = overrideValue ? ForceTrue : ForceFalse;
|
|
}
|
|
|
|
void reset() { mode_ = Default; }
|
|
|
|
private:
|
|
enum Mode { Default, ForceTrue, ForceFalse };
|
|
|
|
Mode mode_;
|
|
};
|
|
|
|
bool extraWarnings(JSContext* cx) const;
|
|
Override& extraWarningsOverride() { return extraWarningsOverride_; }
|
|
|
|
bool getSingletonsAsTemplates() const { return singletonsAsTemplates_; }
|
|
RealmBehaviors& setSingletonsAsValues() {
|
|
singletonsAsTemplates_ = false;
|
|
return *this;
|
|
}
|
|
|
|
// A Realm can stop being "live" in all the ways that matter before its global
|
|
// is actually GCed. Consumers that tear down parts of a Realm or its global
|
|
// before that point should set isNonLive accordingly.
|
|
bool isNonLive() const { return isNonLive_; }
|
|
RealmBehaviors& setNonLive() {
|
|
isNonLive_ = true;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
bool discardSource_ = false;
|
|
bool disableLazyParsing_ = false;
|
|
bool clampAndJitterTime_ = true;
|
|
Override extraWarningsOverride_ = {};
|
|
|
|
// To XDR singletons, we need to ensure that all singletons are all used as
|
|
// templates, by making JSOP_OBJECT return a clone of the JSScript
|
|
// singleton, instead of returning the value which is baked in the JSScript.
|
|
bool singletonsAsTemplates_ = true;
|
|
bool isNonLive_ = false;
|
|
bool deferredParserAlloc_ = true;
|
|
};
|
|
|
|
/**
|
|
* RealmOptions specifies realm characteristics: both those that can't be
|
|
* changed on a realm once it's been created (RealmCreationOptions), and those
|
|
* that can be changed on an existing realm (RealmBehaviors).
|
|
*/
|
|
class JS_PUBLIC_API RealmOptions {
|
|
public:
|
|
explicit RealmOptions() : creationOptions_(), behaviors_() {}
|
|
|
|
RealmOptions(const RealmCreationOptions& realmCreation,
|
|
const RealmBehaviors& realmBehaviors)
|
|
: creationOptions_(realmCreation), behaviors_(realmBehaviors) {}
|
|
|
|
// RealmCreationOptions specify fundamental realm characteristics that must
|
|
// be specified when the realm is created, that can't be changed after the
|
|
// realm is created.
|
|
RealmCreationOptions& creationOptions() { return creationOptions_; }
|
|
const RealmCreationOptions& creationOptions() const {
|
|
return creationOptions_;
|
|
}
|
|
|
|
// RealmBehaviors specify realm characteristics that can be changed after
|
|
// the realm is created.
|
|
RealmBehaviors& behaviors() { return behaviors_; }
|
|
const RealmBehaviors& behaviors() const { return behaviors_; }
|
|
|
|
private:
|
|
RealmCreationOptions creationOptions_;
|
|
RealmBehaviors behaviors_;
|
|
};
|
|
|
|
extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
|
|
Realm* realm);
|
|
|
|
extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
|
|
JSContext* cx);
|
|
|
|
extern JS_PUBLIC_API RealmBehaviors& RealmBehaviorsRef(Realm* realm);
|
|
|
|
extern JS_PUBLIC_API RealmBehaviors& RealmBehaviorsRef(JSContext* cx);
|
|
|
|
} // namespace JS
|
|
|
|
#endif // js_RealmOptions_h
|