Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / public / Transcoding.h
blob9a5c6102ad72532b524f5755e337bf83d149f962
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 * Structures and functions for transcoding compiled scripts and functions to
8 * and from memory.
9 */
11 #ifndef js_Transcoding_h
12 #define js_Transcoding_h
14 #include "mozilla/Range.h" // mozilla::Range
15 #include "mozilla/Vector.h" // mozilla::Vector
17 #include <stddef.h> // size_t
18 #include <stdint.h> // uint8_t, uint32_t
20 #include "js/TypeDecls.h"
22 namespace JS {
24 class JS_PUBLIC_API ReadOnlyCompileOptions;
26 using TranscodeBuffer = mozilla::Vector<uint8_t>;
27 using TranscodeRange = mozilla::Range<const uint8_t>;
29 struct TranscodeSource final {
30 TranscodeSource(const TranscodeRange& range_, const char* file, uint32_t line)
31 : range(range_), filename(file), lineno(line) {}
33 const TranscodeRange range;
34 const char* filename;
35 const uint32_t lineno;
38 enum class TranscodeResult : uint8_t {
39 // Successful encoding / decoding.
40 Ok = 0,
42 // A warning message, is set to the message out-param.
43 Failure = 0x10,
44 Failure_BadBuildId = Failure | 0x1,
45 Failure_AsmJSNotSupported = Failure | 0x2,
46 Failure_BadDecode = Failure | 0x3,
48 // There is a pending exception on the context.
49 Throw = 0x20
52 inline bool IsTranscodeFailureResult(const TranscodeResult result) {
53 uint8_t raw_result = static_cast<uint8_t>(result);
54 uint8_t raw_failure = static_cast<uint8_t>(TranscodeResult::Failure);
55 TranscodeResult masked =
56 static_cast<TranscodeResult>(raw_result & raw_failure);
57 return masked == TranscodeResult::Failure;
60 static constexpr size_t BytecodeOffsetAlignment = 4;
61 static_assert(BytecodeOffsetAlignment <= alignof(std::max_align_t),
62 "Alignment condition requires a custom allocator.");
64 // Align the bytecode offset for transcoding for the requirement.
65 inline size_t AlignTranscodingBytecodeOffset(size_t offset) {
66 size_t extra = offset % BytecodeOffsetAlignment;
67 if (extra == 0) {
68 return offset;
70 size_t padding = BytecodeOffsetAlignment - extra;
71 return offset + padding;
74 inline bool IsTranscodingBytecodeOffsetAligned(size_t offset) {
75 return offset % BytecodeOffsetAlignment == 0;
78 inline bool IsTranscodingBytecodeAligned(const void* offset) {
79 return IsTranscodingBytecodeOffsetAligned(size_t(offset));
82 // Finish incremental encoding started by JS::StartIncrementalEncoding.
84 // * Regular script case
85 // the |script| argument must be the top-level script returned from
86 // |JS::InstantiateGlobalStencil| with the same stencil
88 // * Module script case
89 // the |script| argument must be the script returned by
90 // |JS::GetModuleScript| called on the module returned by
91 // |JS::InstantiateModuleStencil| with the same stencil
93 // NOTE: |JS::GetModuleScript| doesn't work after evaluating the
94 // module script. For the case, use Handle<JSObject*> variant of
95 // this function below.
97 // The |buffer| argument of |FinishIncrementalEncoding| is used for appending
98 // the encoded bytecode into the buffer. If any of these functions failed, the
99 // content of |buffer| would be undefined.
101 // |buffer| contains encoded CompilationStencil.
103 // If the `buffer` isn't empty, the start of the `buffer` should meet
104 // IsTranscodingBytecodeAligned, and the length should meet
105 // IsTranscodingBytecodeOffsetAligned.
107 // NOTE: As long as IsTranscodingBytecodeOffsetAligned is met, that means
108 // there's JS::BytecodeOffsetAlignment+extra bytes in the buffer,
109 // IsTranscodingBytecodeAligned should be guaranteed to meet by
110 // malloc, used by MallocAllocPolicy in mozilla::Vector.
111 extern JS_PUBLIC_API bool FinishIncrementalEncoding(JSContext* cx,
112 Handle<JSScript*> script,
113 TranscodeBuffer& buffer);
115 // Similar to |JS::FinishIncrementalEncoding|, but receives module obect.
117 // The |module| argument must be the module returned by
118 // |JS::InstantiateModuleStencil| with the same stencil that's passed to
119 // |JS::StartIncrementalEncoding|.
120 extern JS_PUBLIC_API bool FinishIncrementalEncoding(JSContext* cx,
121 Handle<JSObject*> module,
122 TranscodeBuffer& buffer);
124 // Abort incremental encoding started by JS::StartIncrementalEncoding.
125 extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle<JSScript*> script);
126 extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle<JSObject*> module);
128 // Check if the compile options and script's flag matches.
130 // JS::DecodeScript* and JS::DecodeOffThreadScript internally check this.
131 extern JS_PUBLIC_API bool CheckCompileOptionsMatch(
132 const ReadOnlyCompileOptions& options, JSScript* script);
134 } // namespace JS
136 #endif /* js_Transcoding_h */