Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / public / CompileOptions.h
blob01a84b23986eb85c4cd8c18862b00f121b5badb9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*
7 * Options for JavaScript compilation.
9 * In the most common use case, a CompileOptions instance is allocated on the
10 * stack, and holds non-owning references to non-POD option values: strings,
11 * principals, objects, and so on. The code declaring the instance guarantees
12 * that such option values will outlive the CompileOptions itself: objects are
13 * otherwise rooted, principals have had their reference counts bumped, and
14 * strings won't be freed until the CompileOptions goes out of scope. In this
15 * situation, CompileOptions only refers to things others own, so it can be
16 * lightweight.
18 * In some cases, however, we need to hold compilation options with a
19 * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
20 * compilation options where a worker thread can find them, then return
21 * immediately. The worker thread will come along at some later point, and use
22 * the options.
24 * The compiler itself just needs to be able to access a collection of options;
25 * it doesn't care who owns them, or what's keeping them alive. It does its
26 * own addrefs/copies/tracing/etc.
28 * Furthermore, in some cases compile options are propagated from one entity to
29 * another (e.g. from a script to a function defined in that script). This
30 * involves copying over some, but not all, of the options.
32 * So we have a class hierarchy that reflects these four use cases:
34 * - TransitiveCompileOptions is the common base class, representing options
35 * that should get propagated from a script to functions defined in that
36 * script. This class is abstract and is only ever used as a subclass.
38 * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions,
39 * representing a full set of compile options. It can be used by code that
40 * simply needs to access options set elsewhere, like the compiler. This
41 * class too is abstract and is only ever used as a subclass.
43 * - The usual CompileOptions class must be stack-allocated, and holds
44 * non-owning references to the filename, element, and so on. It's derived
45 * from ReadOnlyCompileOptions, so the compiler can use it.
47 * - OwningCompileOptions roots / copies / reference counts of all its values,
48 * and unroots / frees / releases them when it is destructed. It too is
49 * derived from ReadOnlyCompileOptions, so the compiler accepts it.
52 #ifndef js_CompileOptions_h
53 #define js_CompileOptions_h
55 #include "mozilla/Assertions.h" // MOZ_ASSERT
56 #include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf
58 #include <stddef.h> // size_t
59 #include <stdint.h> // uint8_t, uint32_t
61 #include "jstypes.h" // JS_PUBLIC_API
63 #include "js/CharacterEncoding.h" // JS::ConstUTF8CharsZ
64 #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
65 #include "js/TypeDecls.h" // JS::MutableHandle (fwd)
67 namespace js {
68 class FrontendContext;
69 } // namespace js
71 namespace JS {
72 using FrontendContext = js::FrontendContext;
74 enum class AsmJSOption : uint8_t {
75 Enabled,
76 DisabledByAsmJSPref,
77 DisabledByLinker,
78 DisabledByNoWasmCompiler,
79 DisabledByDebugger,
82 #define FOREACH_DELAZIFICATION_STRATEGY(_) \
83 /* Do not delazify anything eagerly. */ \
84 _(OnDemandOnly) \
86 /* \
87 * Compare the stencil produced by concurrent depth first delazification and \
88 * on-demand delazification. Any differences would crash SpiderMonkey with \
89 * an assertion. \
90 */ \
91 _(CheckConcurrentWithOnDemand) \
93 /* \
94 * Delazifiy functions in a depth first traversal of the functions. \
95 */ \
96 _(ConcurrentDepthFirst) \
98 /* \
99 * Delazifiy functions strating with the largest function first. \
100 */ \
101 _(ConcurrentLargeFirst) \
103 /* \
104 * Parse everything eagerly, from the first parse. \
106 * NOTE: Either the Realm configuration or specialized VM operating modes \
107 * may disallow syntax-parse altogether. These conditions are checked in the \
108 * CompileOptions constructor. \
109 */ \
110 _(ParseEverythingEagerly)
112 enum class DelazificationOption : uint8_t {
113 #define _ENUM_ENTRY(Name) Name,
114 FOREACH_DELAZIFICATION_STRATEGY(_ENUM_ENTRY)
115 #undef _ENUM_ENTRY
118 class JS_PUBLIC_API InstantiateOptions;
119 class JS_PUBLIC_API ReadOnlyDecodeOptions;
121 // Compilation-specific part of JS::ContextOptions which is supposed to be
122 // configured by user prefs.
123 class JS_PUBLIC_API PrefableCompileOptions {
124 public:
125 PrefableCompileOptions()
126 : importAttributes_(false),
127 importAttributesAssertSyntax_(false),
128 sourcePragmas_(true),
129 throwOnAsmJSValidationFailure_(false) {}
131 bool importAttributes() const { return importAttributes_; }
132 PrefableCompileOptions& setImportAttributes(bool enabled) {
133 importAttributes_ = enabled;
134 return *this;
136 bool importAttributesAssertSyntax() const {
137 return importAttributesAssertSyntax_;
139 PrefableCompileOptions& setImportAttributesAssertSyntax(bool enabled) {
140 importAttributesAssertSyntax_ = enabled;
141 return *this;
144 // Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas.
145 bool sourcePragmas() const { return sourcePragmas_; }
146 PrefableCompileOptions& setSourcePragmas(bool flag) {
147 sourcePragmas_ = flag;
148 return *this;
151 AsmJSOption asmJSOption() const { return asmJSOption_; }
152 PrefableCompileOptions& setAsmJS(bool flag) {
153 asmJSOption_ =
154 flag ? AsmJSOption::Enabled : AsmJSOption::DisabledByAsmJSPref;
155 return *this;
157 PrefableCompileOptions& setAsmJSOption(AsmJSOption option) {
158 asmJSOption_ = option;
159 return *this;
162 bool throwOnAsmJSValidationFailure() const {
163 return throwOnAsmJSValidationFailure_;
165 PrefableCompileOptions& setThrowOnAsmJSValidationFailure(bool flag) {
166 throwOnAsmJSValidationFailure_ = flag;
167 return *this;
169 PrefableCompileOptions& toggleThrowOnAsmJSValidationFailure() {
170 throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
171 return *this;
174 #if defined(DEBUG) || defined(JS_JITSPEW)
175 template <typename Printer>
176 void dumpWith(Printer& print) const {
177 # define PrintFields_(Name) print(#Name, Name)
178 PrintFields_(importAttributes_);
179 PrintFields_(importAttributesAssertSyntax_);
180 PrintFields_(sourcePragmas_);
181 PrintFields_(throwOnAsmJSValidationFailure_);
182 # undef PrintFields_
184 switch (asmJSOption_) {
185 case AsmJSOption::Enabled:
186 print("asmJSOption_", "AsmJSOption::Enabled");
187 break;
188 case AsmJSOption::DisabledByAsmJSPref:
189 print("asmJSOption_", "AsmJSOption::DisabledByAsmJSPref");
190 break;
191 case AsmJSOption::DisabledByLinker:
192 print("asmJSOption_", "AsmJSOption::DisabledByLinker");
193 break;
194 case AsmJSOption::DisabledByNoWasmCompiler:
195 print("asmJSOption_", "AsmJSOption::DisabledByNoWasmCompiler");
196 break;
197 case AsmJSOption::DisabledByDebugger:
198 print("asmJSOption_", "AsmJSOption::DisabledByDebugger");
199 break;
202 #endif // defined(DEBUG) || defined(JS_JITSPEW)
204 private:
205 // ==== Syntax-related options. ====
206 bool importAttributes_ : 1;
207 bool importAttributesAssertSyntax_ : 1;
209 // The context has specified that source pragmas should be parsed.
210 bool sourcePragmas_ : 1;
212 // ==== asm.js options. ====
213 bool throwOnAsmJSValidationFailure_ : 1;
215 AsmJSOption asmJSOption_ = AsmJSOption::DisabledByAsmJSPref;
219 * The common base class for the CompileOptions hierarchy.
221 * Use this in code that needs to propagate compile options from one
222 * compilation unit to another.
224 class JS_PUBLIC_API TransitiveCompileOptions {
225 friend class JS_PUBLIC_API ReadOnlyDecodeOptions;
227 protected:
228 // non-POD options:
230 JS::ConstUTF8CharsZ filename_;
232 JS::ConstUTF8CharsZ introducerFilename_;
234 const char16_t* sourceMapURL_ = nullptr;
236 // POD options:
237 // WARNING: When adding new fields, don't forget to add them to
238 // copyPODTransitiveOptions.
241 * The Web Platform allows scripts to be loaded from arbitrary cross-origin
242 * sources. This allows an attack by which a malicious website loads a
243 * sensitive file (say, a bank statement) cross-origin (using the user's
244 * cookies), and sniffs the generated syntax errors (via a window.onerror
245 * handler) for juicy morsels of its contents.
247 * To counter this attack, HTML5 specifies that script errors should be
248 * sanitized ("muted") when the script is not same-origin with the global
249 * for which it is loaded. Callers should set this flag for cross-origin
250 * scripts, and it will be propagated appropriately to child scripts and
251 * passed back in JSErrorReports.
253 bool mutedErrors_ = false;
255 // Either the Realm configuration or the compile request may force
256 // strict-mode.
257 bool forceStrictMode_ = false;
259 // The Realm of this script is configured to use fdlibm math library.
260 bool alwaysUseFdlibm_ = false;
262 // Flag used to bypass the filename validation callback.
263 // See also SetFilenameValidationCallback.
264 bool skipFilenameValidation_ = false;
266 bool hideScriptFromDebugger_ = false;
268 // If set, this script will be hidden from the debugger. The requirement
269 // is that once compilation is finished, a call to UpdateDebugMetadata will
270 // be made, which will update the SSO with the appropiate debug metadata,
271 // and expose the script to the debugger (if hideScriptFromDebugger_ isn't
272 // set)
273 bool deferDebugMetadata_ = false;
275 // Off-thread delazification strategy is used to tell off-thread tasks how the
276 // delazification should be performed. Multiple strategies are available in
277 // order to test different approaches to the concurrent delazification.
278 DelazificationOption eagerDelazificationStrategy_ =
279 DelazificationOption::OnDemandOnly;
281 friend class JS_PUBLIC_API InstantiateOptions;
283 public:
284 bool selfHostingMode = false;
285 bool discardSource = false;
286 bool sourceIsLazy = false;
287 bool allowHTMLComments = true;
288 bool nonSyntacticScope = false;
290 // Top-level await is enabled by default but is not supported for chrome
291 // modules loaded with ChromeUtils.importModule.
292 bool topLevelAwait = true;
294 // When decoding from XDR into a Stencil, directly reference data in the
295 // buffer (where possible) instead of copying it. This is an optional
296 // performance optimization, and may also reduce memory if the buffer is going
297 // remain alive anyways.
299 // NOTE: The XDR buffer must remain alive as long as the Stencil does. Special
300 // care must be taken that there are no addition shared references to
301 // the Stencil.
303 // NOTE: Instantiated GC things may still outlive the buffer as long as the
304 // Stencil was cleaned up. This is covers a typical case where a decoded
305 // Stencil is instantiated once and then thrown away.
306 bool borrowBuffer = false;
308 // Similar to `borrowBuffer`, but additionally the JSRuntime may directly
309 // reference data in the buffer for JS bytecode. The `borrowBuffer` flag must
310 // be set if this is set. This can be a memory optimization in multi-process
311 // architectures where a (read-only) XDR buffer is mapped into multiple
312 // processes.
314 // NOTE: When using this mode, the XDR buffer must live until JS_Shutdown is
315 // called. There is currently no mechanism to release the data sooner.
316 bool usePinnedBytecode = false;
318 // De-optimize ES module's top-level `var`s, in order to define all of them
319 // on the ModuleEnvironmentObject, instead of local slot.
321 // This is used for providing all global variables in Cu.import return value
322 // (see bug 1766761 for more details), and this is temporary solution until
323 // ESM-ification finishes.
325 // WARNING: This option will eventually be removed.
326 bool deoptimizeModuleGlobalVars = false;
328 PrefableCompileOptions prefableOptions_;
331 * |introductionType| is a statically allocated C string. See JSScript.h
332 * for more information.
334 const char* introductionType = nullptr;
336 unsigned introductionLineno = 0;
337 uint32_t introductionOffset = 0;
338 bool hasIntroductionInfo = false;
340 // WARNING: When adding new fields, don't forget to add them to
341 // copyPODTransitiveOptions.
343 protected:
344 TransitiveCompileOptions() = default;
346 // Set all POD options (those not requiring reference counts, copies,
347 // rooting, or other hand-holding) to their values in |rhs|.
348 void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs);
350 bool isEagerDelazificationEqualTo(DelazificationOption val) const {
351 return eagerDelazificationStrategy() == val;
354 template <DelazificationOption... Values>
355 bool eagerDelazificationIsOneOf() const {
356 return (isEagerDelazificationEqualTo(Values) || ...);
359 public:
360 // Read-only accessors for non-POD options. The proper way to set these
361 // depends on the derived type.
362 bool mutedErrors() const { return mutedErrors_; }
363 bool alwaysUseFdlibm() const { return alwaysUseFdlibm_; }
364 bool forceFullParse() const {
365 return eagerDelazificationIsOneOf<
366 DelazificationOption::ParseEverythingEagerly>();
368 bool forceStrictMode() const { return forceStrictMode_; }
369 bool consumeDelazificationCache() const {
370 return eagerDelazificationIsOneOf<
371 DelazificationOption::ConcurrentDepthFirst,
372 DelazificationOption::ConcurrentLargeFirst>();
374 bool populateDelazificationCache() const {
375 return eagerDelazificationIsOneOf<
376 DelazificationOption::CheckConcurrentWithOnDemand,
377 DelazificationOption::ConcurrentDepthFirst,
378 DelazificationOption::ConcurrentLargeFirst>();
380 bool waitForDelazificationCache() const {
381 return eagerDelazificationIsOneOf<
382 DelazificationOption::CheckConcurrentWithOnDemand>();
384 bool checkDelazificationCache() const {
385 return eagerDelazificationIsOneOf<
386 DelazificationOption::CheckConcurrentWithOnDemand>();
388 DelazificationOption eagerDelazificationStrategy() const {
389 return eagerDelazificationStrategy_;
392 bool importAttributes() const { return prefableOptions_.importAttributes(); }
393 bool importAttributesAssertSyntax() const {
394 return prefableOptions_.importAttributesAssertSyntax();
396 bool sourcePragmas() const { return prefableOptions_.sourcePragmas(); }
397 bool throwOnAsmJSValidationFailure() const {
398 return prefableOptions_.throwOnAsmJSValidationFailure();
400 AsmJSOption asmJSOption() const { return prefableOptions_.asmJSOption(); }
401 void setAsmJSOption(AsmJSOption option) {
402 prefableOptions_.setAsmJSOption(option);
405 JS::ConstUTF8CharsZ filename() const { return filename_; }
406 JS::ConstUTF8CharsZ introducerFilename() const { return introducerFilename_; }
407 const char16_t* sourceMapURL() const { return sourceMapURL_; }
409 const PrefableCompileOptions& prefableOptions() const {
410 return prefableOptions_;
413 TransitiveCompileOptions(const TransitiveCompileOptions&) = delete;
414 TransitiveCompileOptions& operator=(const TransitiveCompileOptions&) = delete;
416 #if defined(DEBUG) || defined(JS_JITSPEW)
417 template <typename Printer>
418 void dumpWith(Printer& print) const {
419 # define PrintFields_(Name) print(#Name, Name)
420 PrintFields_(filename_);
421 PrintFields_(introducerFilename_);
422 PrintFields_(sourceMapURL_);
423 PrintFields_(mutedErrors_);
424 PrintFields_(forceStrictMode_);
425 PrintFields_(alwaysUseFdlibm_);
426 PrintFields_(skipFilenameValidation_);
427 PrintFields_(hideScriptFromDebugger_);
428 PrintFields_(deferDebugMetadata_);
429 PrintFields_(eagerDelazificationStrategy_);
430 PrintFields_(selfHostingMode);
431 PrintFields_(discardSource);
432 PrintFields_(sourceIsLazy);
433 PrintFields_(allowHTMLComments);
434 PrintFields_(nonSyntacticScope);
435 PrintFields_(topLevelAwait);
436 PrintFields_(borrowBuffer);
437 PrintFields_(usePinnedBytecode);
438 PrintFields_(deoptimizeModuleGlobalVars);
439 PrintFields_(introductionType);
440 PrintFields_(introductionLineno);
441 PrintFields_(introductionOffset);
442 PrintFields_(hasIntroductionInfo);
443 # undef PrintFields_
445 prefableOptions_.dumpWith(print);
447 #endif // defined(DEBUG) || defined(JS_JITSPEW)
451 * The class representing a full set of compile options.
453 * Use this in code that only needs to access compilation options created
454 * elsewhere, like the compiler. Don't instantiate this class (the constructor
455 * is protected anyway); instead, create instances only of the derived classes:
456 * CompileOptions and OwningCompileOptions.
458 class JS_PUBLIC_API ReadOnlyCompileOptions : public TransitiveCompileOptions {
459 public:
460 // POD options.
462 // Line number of the first character (1-origin).
463 uint32_t lineno = 1;
464 // Column number of the first character in UTF-16 code units.
465 JS::ColumnNumberOneOrigin column;
467 // The offset within the ScriptSource's full uncompressed text of the first
468 // character we're presenting for compilation with this CompileOptions.
470 // When we compile a lazy script, we pass the compiler only the substring of
471 // the source the lazy function occupies. With chunked decompression, we may
472 // not even have the complete uncompressed source present in memory. But parse
473 // node positions are offsets within the ScriptSource's full text, and
474 // BaseScript indicate their substring of the full source by its starting and
475 // ending offsets within the full text. This scriptSourceOffset field lets the
476 // frontend convert between these offsets and offsets within the substring
477 // presented for compilation.
478 unsigned scriptSourceOffset = 0;
480 // These only apply to non-function scripts.
481 bool isRunOnce = false;
482 bool noScriptRval = false;
484 protected:
485 ReadOnlyCompileOptions() = default;
487 void copyPODNonTransitiveOptions(const ReadOnlyCompileOptions& rhs);
489 ReadOnlyCompileOptions(const ReadOnlyCompileOptions&) = delete;
490 ReadOnlyCompileOptions& operator=(const ReadOnlyCompileOptions&) = delete;
492 public:
493 #if defined(DEBUG) || defined(JS_JITSPEW)
494 template <typename Printer>
495 void dumpWith(Printer& print) const {
496 this->TransitiveCompileOptions::dumpWith(print);
497 # define PrintFields_(Name) print(#Name, Name)
498 PrintFields_(lineno);
499 print("column", column.oneOriginValue());
500 PrintFields_(scriptSourceOffset);
501 PrintFields_(isRunOnce);
502 PrintFields_(noScriptRval);
503 # undef PrintFields_
505 #endif // defined(DEBUG) || defined(JS_JITSPEW)
508 class JS_PUBLIC_API OwningDecodeOptions;
511 * Compilation options, with dynamic lifetime. An instance of this type
512 * makes a copy of / holds / roots all dynamically allocated resources
513 * (principals; elements; strings) that it refers to. Its destructor frees
514 * / drops / unroots them. This is heavier than CompileOptions, below, but
515 * unlike CompileOptions, it can outlive any given stack frame.
517 * Note that this *roots* any JS values it refers to - they're live
518 * unconditionally. Thus, instances of this type can't be owned, directly
519 * or indirectly, by a JavaScript object: if any value that this roots ever
520 * comes to refer to the object that owns this, then the whole cycle, and
521 * anything else it entrains, will never be freed.
523 class JS_PUBLIC_API OwningCompileOptions final : public ReadOnlyCompileOptions {
524 public:
525 // A minimal constructor, for use with OwningCompileOptions::copy.
526 explicit OwningCompileOptions(JSContext* cx);
528 struct ForFrontendContext {};
529 explicit OwningCompileOptions(const ForFrontendContext&)
530 : ReadOnlyCompileOptions() {}
532 ~OwningCompileOptions();
534 private:
535 template <typename ContextT>
536 bool copyImpl(ContextT* cx, const ReadOnlyCompileOptions& rhs);
538 public:
539 /** Set this to a copy of |rhs|. Return false on OOM. */
540 bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs);
541 bool copy(JS::FrontendContext* fc, const ReadOnlyCompileOptions& rhs);
543 void steal(OwningCompileOptions&& rhs);
544 void steal(OwningDecodeOptions&& rhs);
546 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
548 OwningCompileOptions& setIsRunOnce(bool once) {
549 isRunOnce = once;
550 return *this;
553 OwningCompileOptions& setForceStrictMode() {
554 forceStrictMode_ = true;
555 return *this;
558 OwningCompileOptions& setModule() {
559 // ES6 10.2.1 Module code is always strict mode code.
560 setForceStrictMode();
561 setIsRunOnce(true);
562 allowHTMLComments = false;
563 return *this;
566 private:
567 void release();
569 OwningCompileOptions(const OwningCompileOptions&) = delete;
570 OwningCompileOptions& operator=(const OwningCompileOptions&) = delete;
574 * Compilation options stored on the stack. An instance of this type
575 * simply holds references to dynamically allocated resources (element;
576 * filename; source map URL) that are owned by something else. If you
577 * create an instance of this type, it's up to you to guarantee that
578 * everything you store in it will outlive it.
580 class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final
581 : public ReadOnlyCompileOptions {
582 public:
583 // Default options determined using the JSContext.
584 explicit CompileOptions(JSContext* cx);
586 // Copy both the transitive and the non-transitive options from another
587 // options object.
588 CompileOptions(JSContext* cx, const ReadOnlyCompileOptions& rhs)
589 : ReadOnlyCompileOptions() {
590 copyPODNonTransitiveOptions(rhs);
591 copyPODTransitiveOptions(rhs);
593 filename_ = rhs.filename();
594 introducerFilename_ = rhs.introducerFilename();
595 sourceMapURL_ = rhs.sourceMapURL();
598 // Construct a CompileOption in the context where JSContext is not available.
599 // prefableOptions should reflect the compilation-specific user prefs.
600 explicit CompileOptions(const PrefableCompileOptions& prefableOptions)
601 : ReadOnlyCompileOptions() {
602 prefableOptions_ = prefableOptions;
605 CompileOptions& setFile(const char* f) {
606 filename_ = JS::ConstUTF8CharsZ(f);
607 return *this;
610 CompileOptions& setLine(uint32_t l) {
611 lineno = l;
612 return *this;
615 CompileOptions& setFileAndLine(const char* f, uint32_t l) {
616 filename_ = JS::ConstUTF8CharsZ(f);
617 lineno = l;
618 return *this;
621 CompileOptions& setSourceMapURL(const char16_t* s) {
622 sourceMapURL_ = s;
623 return *this;
626 CompileOptions& setMutedErrors(bool mute) {
627 mutedErrors_ = mute;
628 return *this;
631 CompileOptions& setColumn(JS::ColumnNumberOneOrigin c) {
632 column = c;
633 return *this;
636 CompileOptions& setScriptSourceOffset(unsigned o) {
637 scriptSourceOffset = o;
638 return *this;
641 CompileOptions& setIsRunOnce(bool once) {
642 isRunOnce = once;
643 return *this;
646 CompileOptions& setNoScriptRval(bool nsr) {
647 noScriptRval = nsr;
648 return *this;
651 CompileOptions& setSkipFilenameValidation(bool b) {
652 skipFilenameValidation_ = b;
653 return *this;
656 CompileOptions& setSelfHostingMode(bool shm) {
657 selfHostingMode = shm;
658 return *this;
661 CompileOptions& setSourceIsLazy(bool l) {
662 sourceIsLazy = l;
663 return *this;
666 CompileOptions& setNonSyntacticScope(bool n) {
667 nonSyntacticScope = n;
668 return *this;
671 CompileOptions& setIntroductionType(const char* t) {
672 introductionType = t;
673 return *this;
676 CompileOptions& setDeferDebugMetadata(bool v = true) {
677 deferDebugMetadata_ = v;
678 return *this;
681 CompileOptions& setHideScriptFromDebugger(bool v = true) {
682 hideScriptFromDebugger_ = v;
683 return *this;
686 CompileOptions& setIntroductionInfo(const char* introducerFn,
687 const char* intro, uint32_t line,
688 uint32_t offset) {
689 introducerFilename_ = JS::ConstUTF8CharsZ(introducerFn);
690 introductionType = intro;
691 introductionLineno = line;
692 introductionOffset = offset;
693 hasIntroductionInfo = true;
694 return *this;
697 // Set introduction information according to any currently executing script.
698 CompileOptions& setIntroductionInfoToCaller(
699 JSContext* cx, const char* introductionType,
700 JS::MutableHandle<JSScript*> introductionScript);
702 CompileOptions& setDiscardSource() {
703 discardSource = true;
704 return *this;
707 CompileOptions& setForceFullParse() {
708 eagerDelazificationStrategy_ = DelazificationOption::ParseEverythingEagerly;
709 return *this;
712 CompileOptions& setEagerDelazificationStrategy(
713 DelazificationOption strategy) {
714 // forceFullParse is at the moment considered as a non-overridable strategy.
715 MOZ_RELEASE_ASSERT(eagerDelazificationStrategy_ !=
716 DelazificationOption::ParseEverythingEagerly ||
717 strategy ==
718 DelazificationOption::ParseEverythingEagerly);
719 eagerDelazificationStrategy_ = strategy;
720 return *this;
723 CompileOptions& setForceStrictMode() {
724 forceStrictMode_ = true;
725 return *this;
728 CompileOptions& setModule() {
729 // ES6 10.2.1 Module code is always strict mode code.
730 setForceStrictMode();
731 setIsRunOnce(true);
732 allowHTMLComments = false;
733 return *this;
736 CompileOptions(const CompileOptions& rhs) = delete;
737 CompileOptions& operator=(const CompileOptions& rhs) = delete;
741 * Subset of CompileOptions fields used while instantiating Stencils.
743 class JS_PUBLIC_API InstantiateOptions {
744 public:
745 bool skipFilenameValidation = false;
746 bool hideScriptFromDebugger = false;
747 bool deferDebugMetadata = false;
749 InstantiateOptions() = default;
751 explicit InstantiateOptions(const ReadOnlyCompileOptions& options)
752 : skipFilenameValidation(options.skipFilenameValidation_),
753 hideScriptFromDebugger(options.hideScriptFromDebugger_),
754 deferDebugMetadata(options.deferDebugMetadata_) {}
756 void copyTo(CompileOptions& options) const {
757 options.skipFilenameValidation_ = skipFilenameValidation;
758 options.hideScriptFromDebugger_ = hideScriptFromDebugger;
759 options.deferDebugMetadata_ = deferDebugMetadata;
762 bool hideFromNewScriptInitial() const {
763 return deferDebugMetadata || hideScriptFromDebugger;
766 #ifdef DEBUG
767 // Assert that all fields have default value.
769 // This can be used when instantiation is performed as separate step than
770 // compile-to-stencil, and CompileOptions isn't available there.
771 void assertDefault() const {
772 MOZ_ASSERT(skipFilenameValidation == false);
773 MOZ_ASSERT(hideScriptFromDebugger == false);
774 MOZ_ASSERT(deferDebugMetadata == false);
776 #endif
780 * Subset of CompileOptions fields used while decoding Stencils.
782 class JS_PUBLIC_API ReadOnlyDecodeOptions {
783 public:
784 bool borrowBuffer = false;
785 bool usePinnedBytecode = false;
787 protected:
788 JS::ConstUTF8CharsZ introducerFilename_;
790 public:
791 // See `TransitiveCompileOptions::introductionType` field for details.
792 const char* introductionType = nullptr;
794 uint32_t introductionLineno = 0;
795 uint32_t introductionOffset = 0;
797 protected:
798 ReadOnlyDecodeOptions() = default;
800 ReadOnlyDecodeOptions(const ReadOnlyDecodeOptions&) = delete;
801 ReadOnlyDecodeOptions& operator=(const ReadOnlyDecodeOptions&) = delete;
803 template <typename T>
804 void copyPODOptionsFrom(const T& options) {
805 borrowBuffer = options.borrowBuffer;
806 usePinnedBytecode = options.usePinnedBytecode;
807 introductionType = options.introductionType;
808 introductionLineno = options.introductionLineno;
809 introductionOffset = options.introductionOffset;
812 template <typename T>
813 void copyPODOptionsTo(T& options) const {
814 options.borrowBuffer = borrowBuffer;
815 options.usePinnedBytecode = usePinnedBytecode;
816 options.introductionType = introductionType;
817 options.introductionLineno = introductionLineno;
818 options.introductionOffset = introductionOffset;
821 public:
822 void copyTo(CompileOptions& options) const {
823 copyPODOptionsTo(options);
824 options.introducerFilename_ = introducerFilename_;
827 JS::ConstUTF8CharsZ introducerFilename() const { return introducerFilename_; }
830 class MOZ_STACK_CLASS JS_PUBLIC_API DecodeOptions final
831 : public ReadOnlyDecodeOptions {
832 public:
833 DecodeOptions() = default;
835 explicit DecodeOptions(const ReadOnlyCompileOptions& options) {
836 copyPODOptionsFrom(options);
838 introducerFilename_ = options.introducerFilename();
842 class JS_PUBLIC_API OwningDecodeOptions final : public ReadOnlyDecodeOptions {
843 friend class OwningCompileOptions;
845 public:
846 OwningDecodeOptions() = default;
848 ~OwningDecodeOptions();
850 bool copy(JS::FrontendContext* maybeFc, const ReadOnlyDecodeOptions& rhs);
851 void infallibleCopy(const ReadOnlyDecodeOptions& rhs);
853 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
855 private:
856 void release();
858 OwningDecodeOptions(const OwningDecodeOptions&) = delete;
859 OwningDecodeOptions& operator=(const OwningDecodeOptions&) = delete;
862 } // namespace JS
864 #endif /* js_CompileOptions_h */