summaryrefslogtreecommitdiffstats
path: root/js/public/Transcoding.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /js/public/Transcoding.h
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/public/Transcoding.h')
-rw-r--r--js/public/Transcoding.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/js/public/Transcoding.h b/js/public/Transcoding.h
new file mode 100644
index 0000000000..ca0828330a
--- /dev/null
+++ b/js/public/Transcoding.h
@@ -0,0 +1,143 @@
+/* -*- 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/. */
+
+/*
+ * Structures and functions for transcoding compiled scripts and functions to
+ * and from memory.
+ */
+
+#ifndef js_Transcoding_h
+#define js_Transcoding_h
+
+#include "mozilla/Range.h" // mozilla::Range
+#include "mozilla/Vector.h" // mozilla::Vector
+
+#include <stddef.h> // size_t
+#include <stdint.h> // uint8_t, uint32_t
+
+#include "js/TypeDecls.h"
+
+namespace JS {
+
+class JS_PUBLIC_API ReadOnlyCompileOptions;
+
+using TranscodeBuffer = mozilla::Vector<uint8_t>;
+using TranscodeRange = mozilla::Range<const uint8_t>;
+
+struct TranscodeSource final {
+ TranscodeSource(const TranscodeRange& range_, const char* file, uint32_t line)
+ : range(range_), filename(file), lineno(line) {}
+
+ const TranscodeRange range;
+ const char* filename;
+ const uint32_t lineno;
+};
+
+using TranscodeSources = mozilla::Vector<TranscodeSource>;
+
+enum class TranscodeResult : uint8_t {
+ // Successful encoding / decoding.
+ Ok = 0,
+
+ // A warning message, is set to the message out-param.
+ Failure = 0x10,
+ Failure_BadBuildId = Failure | 0x1,
+ Failure_AsmJSNotSupported = Failure | 0x2,
+ Failure_BadDecode = Failure | 0x3,
+
+ // There is a pending exception on the context.
+ Throw = 0x20
+};
+
+inline bool IsTranscodeFailureResult(const TranscodeResult result) {
+ uint8_t raw_result = static_cast<uint8_t>(result);
+ uint8_t raw_failure = static_cast<uint8_t>(TranscodeResult::Failure);
+ TranscodeResult masked =
+ static_cast<TranscodeResult>(raw_result & raw_failure);
+ return masked == TranscodeResult::Failure;
+}
+
+static constexpr size_t BytecodeOffsetAlignment = 4;
+static_assert(BytecodeOffsetAlignment <= alignof(std::max_align_t),
+ "Alignment condition requires a custom allocator.");
+
+// Align the bytecode offset for transcoding for the requirement.
+inline size_t AlignTranscodingBytecodeOffset(size_t offset) {
+ size_t extra = offset % BytecodeOffsetAlignment;
+ if (extra == 0) {
+ return offset;
+ }
+ size_t padding = BytecodeOffsetAlignment - extra;
+ return offset + padding;
+}
+
+inline bool IsTranscodingBytecodeOffsetAligned(size_t offset) {
+ return offset % BytecodeOffsetAlignment == 0;
+}
+
+inline bool IsTranscodingBytecodeAligned(const void* offset) {
+ return IsTranscodingBytecodeOffsetAligned(size_t(offset));
+}
+
+// Finish incremental encoding started by JS::StartIncrementalEncoding.
+//
+// * Regular script case
+// the |script| argument must be the top-level script returned from
+// |JS::InstantiateGlobalStencil| with the same stencil
+//
+// * Module script case
+// the |script| argument must be the script returned by
+// |JS::GetModuleScript| called on the module returned by
+// |JS::InstantiateModuleStencil| with the same stencil
+//
+// NOTE: |JS::GetModuleScript| doesn't work after evaluating the
+// module script. For the case, use Handle<JSObject*> variant of
+// this function below.
+//
+// The |buffer| argument of |FinishIncrementalEncoding| is used for appending
+// the encoded bytecode into the buffer. If any of these functions failed, the
+// content of |buffer| would be undefined.
+//
+// |buffer| contains encoded CompilationStencil.
+//
+// If the `buffer` isn't empty, the start of the `buffer` should meet
+// IsTranscodingBytecodeAligned, and the length should meet
+// IsTranscodingBytecodeOffsetAligned.
+//
+// NOTE: As long as IsTranscodingBytecodeOffsetAligned is met, that means
+// there's JS::BytecodeOffsetAlignment+extra bytes in the buffer,
+// IsTranscodingBytecodeAligned should be guaranteed to meet by
+// malloc, used by MallocAllocPolicy in mozilla::Vector.
+extern JS_PUBLIC_API bool FinishIncrementalEncoding(JSContext* cx,
+ Handle<JSScript*> script,
+ TranscodeBuffer& buffer);
+
+// Similar to |JS::FinishIncrementalEncoding|, but receives module obect.
+//
+// The |module| argument must be the module returned by
+// |JS::InstantiateModuleStencil| with the same stencil that's passed to
+// |JS::StartIncrementalEncoding|.
+extern JS_PUBLIC_API bool FinishIncrementalEncoding(JSContext* cx,
+ Handle<JSObject*> module,
+ TranscodeBuffer& buffer);
+
+// Abort incremental encoding started by JS::StartIncrementalEncoding.
+extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle<JSScript*> script);
+extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle<JSObject*> module);
+
+// Check if the compile options and script's flag matches.
+//
+// JS::DecodeScript* and JS::DecodeOffThreadScript internally check this.
+//
+// JS::DecodeMultiStencilsOffThread checks some options shared across multiple
+// scripts. Caller is responsible for checking each script with this API when
+// using the decoded script instead of compiling a new script wiht the given
+// options.
+extern JS_PUBLIC_API bool CheckCompileOptionsMatch(
+ const ReadOnlyCompileOptions& options, JSScript* script);
+
+} // namespace JS
+
+#endif /* js_Transcoding_h */