summaryrefslogtreecommitdiffstats
path: root/js/public/Prefs.h
blob: 374b5bdbee1a76443872f7f954fc04e6369f6f8c (plain)
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
/* -*- 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_Prefs_h
#define js_Prefs_h

#include "js/PrefsGenerated.h"

// [SMDOC] Prefs
//
// JS::Prefs is used to make JS preferences defined in StaticPrefList.yaml
// available to SpiderMonkey code.
//
// Adding a Pref
// =============
// Adding a new pref is easy. For example, if you're adding a new JS feature,
// you could add the following to StaticPrefList.yaml:
//
//   - name: javascript.options.experimental.my_new_feature
//     type: bool
//     value: false
//     mirror: always
//     set_spidermonkey_pref: startup
//
// The value of this pref can then be accessed in SpiderMonkey code with
// |JS::Prefs::experimental_my_new_feature()|.
//
// The default pref value in the YAML file applies to all SpiderMonkey builds
// (browser, JS shell, jsapi-tests, etc), so by default this feature will be
// disabled everywhere.
//
// To enable your feature, use the |--setpref experimental.my_new_feature=true|
// JS shell command line argument, or set the browser pref in about:config.
// Because this is a 'startup' pref, a browser restart is required for this to
// take effect.
//
// The rest of this comment describes more advanced use cases.
//
// Non-startup prefs
// =================
// Setting |set_spidermonkey_pref = startup| is recommended for most prefs.
// In this case the pref is only set during startup so we don't have to worry
// about the pref value changing at runtime.
//
// However, for some prefs this doesn't work. For instance, the WPT test harness
// can set test-specific prefs after startup. To properly update the JS pref in
// this case, |set_spidermonkey_pref = always| must be used. This means the
// SpiderMonkey pref will be updated whenever it's changed in the browser.
//
// Setting Prefs
// =============
// Embedders can override pref values. For startup prefs, this should only be
// done during startup (before calling JS_Init*) to avoid races with worker
// threads and to avoid confusing code with unexpected pref changes:
//
//   JS::Prefs::setAtStartup_experimental_my_new_feature(true);
//
// Non-startup prefs can also be changed after startup:
//
//   JS::Prefs::set_experimental_my_new_feature(true);
//
// JS Shell Prefs
// ==============
// The JS shell |--list-prefs| command line flag will print a list of all of the
// available JS prefs and their current values.
//
// To change a pref, use |--setpref name=value|, for example
// |--setpref experimental.my_new_feature=true|.
//
// It's also possible to add a custom shell flag. In this case you have to
// override the pref value yourself based on this flag.
//
// Testing Functions
// =================
// The |getAllPrefNames()| function will return an array with all JS pref names.
//
// The |getPrefValue(name)| function can be used to look up the value of the
// given pref. For example, use |getPrefValue("experimental.my_new_feature")|
// for the pref defined above.

namespace JS {

class Prefs {
  // For each pref, define a static |pref_| member.
  JS_PREF_CLASS_FIELDS;

#ifdef DEBUG
  static void assertCanSetStartupPref();
#else
  static void assertCanSetStartupPref() {}
#endif

 public:
  // For each pref, define static getter/setter accessors.
#define DEF_GETSET(NAME, CPP_NAME, TYPE, SETTER, IS_STARTUP_PREF) \
  static TYPE CPP_NAME() { return CPP_NAME##_; }                  \
  static void SETTER(TYPE value) {                                \
    if (IS_STARTUP_PREF) {                                        \
      assertCanSetStartupPref();                                  \
    }                                                             \
    CPP_NAME##_ = value;                                          \
  }
  FOR_EACH_JS_PREF(DEF_GETSET)
#undef DEF_GETSET
};

/**
 * Specification for whether weak refs should be enabled and if so whether the
 * FinalizationRegistry.cleanupSome method should be present.
 */
enum class WeakRefSpecifier {
  Disabled,
  EnabledWithCleanupSome,
  EnabledWithoutCleanupSome
};

inline WeakRefSpecifier GetWeakRefsEnabled() {
  if (!Prefs::weakrefs()) {
    return WeakRefSpecifier::Disabled;
  }
  if (Prefs::experimental_weakrefs_expose_cleanupSome()) {
    return WeakRefSpecifier::EnabledWithCleanupSome;
  }
  return WeakRefSpecifier::EnabledWithoutCleanupSome;
}

};  // namespace JS

#endif /* js_Prefs_h */