/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99:
*/ /* 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/. */
// Evaluate the provided source text, containing a function named // |functionName|.
JS::SourceText<Unit> sourceText; if (!sourceText.init(cx, std::move(chars), len)) { return nullptr;
}
template <typename Unit> staticvoid WriteFunctionOfSizeAtOffset(Source<Unit>& source,
size_t usableSourceLen, char functionName,
size_t functionLength, size_t offset) {
MOZ_RELEASE_ASSERT(functionLength >= MinimumCompressibleLength, "function must be a certain size to be compressed");
MOZ_RELEASE_ASSERT(offset <= usableSourceLen, "offset must not exceed usable source");
MOZ_RELEASE_ASSERT(functionLength <= usableSourceLen, "function must fit in usable source");
MOZ_RELEASE_ASSERT(offset <= usableSourceLen - functionLength, "function must not extend past usable source");
// Assigning |char| to |char16_t| is permitted, but we deliberately require a // cast to assign |char| to |Utf8Unit|. |std::copy_n| would handle the first // case, but the required transformation for UTF-8 demands |std::transform|. auto TransformToUnit = [](char c) { return Unit(c); };
// Fill in the function start.
std::transform(FunctionStart, FunctionStart + FunctionStartLength,
&source[offset], TransformToUnit);
source[offset + FunctionNameOffset] = Unit(functionName);
// Fill in the function end.
std::transform(FunctionEnd, FunctionEnd + FunctionEndLength,
&source[offset + functionLength - FunctionEndLength],
TransformToUnit);
}
template <typename Unit> bool run() {
constexpr size_t len = MinimumCompressibleLength + 55; auto source = MakeSourceAllWhitespace<Unit>(cx, len);
CHECK(source);
// Write out a 'b' or 'c' function that is long enough to be compressed, // that starts after source start and ends before source end.
constexpr char FunctionName = 'a' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName,
MinimumCompressibleLength,
len - MinimumCompressibleLength);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
template <typename Unit> bool run() {
constexpr size_t len = ChunkSize / sizeof(Unit); auto source = MakeSourceAllWhitespace<Unit>(cx, len);
CHECK(source);
// Write out a 'd' or 'e' function that is long enough to be compressed, // that (for no particular reason) starts after source start and ends // before usable source end.
constexpr char FunctionName = 'c' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName,
MinimumCompressibleLength,
len - MinimumCompressibleLength);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
template <typename Unit> bool run() {
constexpr size_t len = ChunkSize / sizeof(Unit); auto source = MakeSourceAllWhitespace<Unit>(cx, len);
CHECK(source);
// Write out a 'f' or 'g' function that occupies the entire source (and // entire chunk, too).
constexpr char FunctionName = 'e' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName, len, 0);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
template <typename Unit> bool run() { // Exactly two chunks.
constexpr size_t len = (2 * ChunkSize) / sizeof(Unit); auto source = MakeSourceAllWhitespace<Unit>(cx, len);
CHECK(source);
// This function crosses a chunk boundary, and it ends exactly at the end // of both the second chunk and the full source.
constexpr size_t FunctionSize = 1 + ChunkSize / sizeof(Unit);
// Write out a 'j' or 'k' function.
constexpr char FunctionName = 'i' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName, FunctionSize,
len - FunctionSize);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
// This function crosses two chunk boundaries and begins/ends in the middle // of chunk boundaries.
constexpr size_t FunctionSize = 2 + ChunkSize / sizeof(Unit);
// Write out a 'l' or 'm' function.
constexpr char FunctionName = 'k' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName, FunctionSize,
ChunkSize / sizeof(Unit) - 1);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
template <typename Unit> bool run() { // Four chunks.
constexpr size_t len = (4 * ChunkSize) / sizeof(Unit); auto source = MakeSourceAllWhitespace<Unit>(cx, len);
CHECK(source);
// This function spans the two middle chunks and further extends one // character to each side.
constexpr size_t FunctionSize = 2 + (2 * ChunkSize) / sizeof(Unit);
// Write out a 'p' or 'q' function.
constexpr char FunctionName = 'o' + sizeof(Unit);
WriteFunctionOfSizeAtOffset(source, len, FunctionName, FunctionSize,
ChunkSize / sizeof(Unit) - 1);
JS::Rooted<JSFunction*> fun(cx);
fun = EvaluateChars(cx, std::move(source), len, FunctionName, __FUNCTION__);
CHECK(fun);
// Check that source compression was triggered by the compile. If the // off-thread source compression system is globally disabled, the source will // remain uncompressed.
js::RunPendingSourceCompressions(cx->runtime()); bool expected = js::IsOffThreadSourceCompressionEnabled();
CHECK(script->scriptSource()->hasCompressedSource() == expected);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.