summaryrefslogtreecommitdiffstats
path: root/js/public/Transcoding.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/public/Transcoding.h
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--js/public/Transcoding.h190
1 files changed, 190 insertions, 0 deletions
diff --git a/js/public/Transcoding.h b/js/public/Transcoding.h
new file mode 100644
index 0000000000..c386fc2539
--- /dev/null
+++ b/js/public/Transcoding.h
@@ -0,0 +1,190 @@
+/* -*- 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 ReadOnlyCompileOptions;
+
+using TranscodeBuffer = mozilla::Vector<uint8_t>;
+using TranscodeRange = mozilla::Range<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 TranscodeResult : uint8_t {
+ // Successful encoding / decoding.
+ TranscodeResult_Ok = 0,
+
+ // A warning message, is set to the message out-param.
+ TranscodeResult_Failure = 0x10,
+ TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1,
+ TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
+ TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3,
+ TranscodeResult_Failure_BadDecode = TranscodeResult_Failure | 0x4,
+ TranscodeResult_Failure_WrongCompileOption = TranscodeResult_Failure | 0x5,
+ TranscodeResult_Failure_NotInterpretedFun = TranscodeResult_Failure | 0x6,
+
+ // There is a pending exception on the context.
+ TranscodeResult_Throw = 0x20
+};
+
+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(void* offset) {
+ return IsTranscodingBytecodeOffsetAligned(size_t(offset));
+}
+
+// Encode JSScript into the buffer.
+//
+// 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 TranscodeResult EncodeScript(JSContext* cx,
+ TranscodeBuffer& buffer,
+ Handle<JSScript*> script);
+
+// Decode JSScript from the buffer.
+//
+// The start of `buffer` and `cursorIndex` should meet
+// IsTranscodingBytecodeAligned and IsTranscodingBytecodeOffsetAligned.
+// (This should be handled while encoding).
+extern JS_PUBLIC_API TranscodeResult
+DecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options,
+ TranscodeBuffer& buffer, MutableHandle<JSScript*> scriptp,
+ size_t cursorIndex = 0);
+
+// Decode JSScript from the range.
+//
+// The start of `range` should meet IsTranscodingBytecodeAligned and
+// IsTranscodingBytecodeOffsetAligned.
+// (This should be handled while encoding).
+extern JS_PUBLIC_API TranscodeResult
+DecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options,
+ const TranscodeRange& range, MutableHandle<JSScript*> scriptp);
+
+// If js::UseOffThreadParseGlobal is true, decode JSScript from the buffer.
+//
+// If js::UseOffThreadParseGlobal is false, decode CompilationStencil from the
+// buffer and instantiate JSScript from it.
+//
+// options.useOffThreadParseGlobal should match JS::SetUseOffThreadParseGlobal.
+//
+// The start of `buffer` and `cursorIndex` should meet
+// IsTranscodingBytecodeAligned and IsTranscodingBytecodeOffsetAligned.
+// (This should be handled while encoding).
+extern JS_PUBLIC_API TranscodeResult DecodeScriptMaybeStencil(
+ JSContext* cx, const ReadOnlyCompileOptions& options,
+ TranscodeBuffer& buffer, MutableHandle<JSScript*> scriptp,
+ size_t cursorIndex = 0);
+
+// If js::UseOffThreadParseGlobal is true, decode JSScript from the buffer.
+//
+// If js::UseOffThreadParseGlobal is false, decode CompilationStencil from the
+// buffer and instantiate JSScript from it.
+//
+// And then register an encoder on its script source, such that all functions
+// can be encoded as they are parsed. This strategy is used to avoid blocking
+// the main thread in a non-interruptible way.
+//
+// See also JS::FinishIncrementalEncoding.
+//
+// options.useOffThreadParseGlobal should match JS::SetUseOffThreadParseGlobal.
+//
+// The start of `buffer` and `cursorIndex` should meet
+// IsTranscodingBytecodeAligned and IsTranscodingBytecodeOffsetAligned.
+// (This should be handled while encoding).
+extern JS_PUBLIC_API TranscodeResult DecodeScriptAndStartIncrementalEncoding(
+ JSContext* cx, const ReadOnlyCompileOptions& options,
+ TranscodeBuffer& buffer, MutableHandle<JSScript*> scriptp,
+ size_t cursorIndex = 0);
+
+// Finish incremental encoding started by one of:
+// * JS::CompileAndStartIncrementalEncoding
+// * JS::FinishOffThreadScriptAndStartIncrementalEncoding
+// * JS::DecodeScriptAndStartIncrementalEncoding
+//
+// The |script| argument of |FinishIncrementalEncoding| should be the top-level
+// script returned from one of the above.
+//
+// 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.
+//
+// If js::UseOffThreadParseGlobal is true, |buffer| contains encoded JSScript.
+//
+// If js::UseOffThreadParseGlobal is false, |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);
+
+// Check if the compile options and script's flag matches.
+//
+// JS::DecodeScript* and JS::DecodeOffThreadScript internally check this.
+//
+// JS::DecodeMultiOffThreadScripts 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 */