From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- js/public/Transcoding.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 js/public/Transcoding.h (limited to 'js/public/Transcoding.h') 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 // size_t +#include // uint8_t, uint32_t + +#include "js/TypeDecls.h" + +namespace JS { + +class JS_PUBLIC_API ReadOnlyCompileOptions; + +using TranscodeBuffer = mozilla::Vector; +using TranscodeRange = mozilla::Range; + +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; + +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(result); + uint8_t raw_failure = static_cast(TranscodeResult::Failure); + TranscodeResult masked = + static_cast(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 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 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 module, + TranscodeBuffer& buffer); + +// Abort incremental encoding started by JS::StartIncrementalEncoding. +extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle script); +extern JS_PUBLIC_API void AbortIncrementalEncoding(Handle 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 */ -- cgit v1.2.3