Bug 1757833 - Extract methods ScriptBytecodeCompress and ScriptBytecodeDecompress r=nbp
This leaves the code in ScriptLoader and ScriptLoadHandler a lot more readable. ScriptBytecodeCompressedDataLayout and ScriptBytecodeDataLayout simplify locating data in the ScriptLoadRequest bytecode buffer when compressing and decompressing it. The interface is still error-prone. For example, these classes don't check that the returned pointers are within the bounds of the buffer. Differential Revision: https://phabricator.services.mozilla.com/D145011
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <utility>
|
||||
#include "ScriptCompression.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "ScriptTrace.h"
|
||||
#include "js/Transcoding.h"
|
||||
@@ -40,14 +41,6 @@
|
||||
#include "nsTArray.h"
|
||||
#include "zlib.h"
|
||||
|
||||
namespace {
|
||||
// A LengthPrefixType is stored at the start of the compressed optimized
|
||||
// encoding, allowing the decompressed buffer to be allocated to exactly
|
||||
// the right size.
|
||||
using LengthPrefixType = uint32_t;
|
||||
const unsigned PREFIX_BYTES = sizeof(LengthPrefixType);
|
||||
} // namespace
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
#undef LOG
|
||||
@@ -410,45 +403,14 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
|
||||
|
||||
mRequest->mBytecodeOffset = JS::AlignTranscodingBytecodeOffset(sriLength);
|
||||
|
||||
{
|
||||
Vector<uint8_t>
|
||||
compressedBytecode; // starts with SRI hash, followed by length
|
||||
// prefix, then compressed bytecode
|
||||
compressedBytecode.swap(mRequest->mScriptBytecode);
|
||||
|
||||
LengthPrefixType uncompressedLength;
|
||||
memcpy(&uncompressedLength,
|
||||
compressedBytecode.begin() + mRequest->mBytecodeOffset,
|
||||
PREFIX_BYTES);
|
||||
if (!mRequest->mScriptBytecode.resizeUninitialized(
|
||||
mRequest->mBytecodeOffset + uncompressedLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(mRequest->mScriptBytecode.begin(), compressedBytecode.begin(),
|
||||
mRequest->mBytecodeOffset); // SRI hash
|
||||
|
||||
z_stream zstream{.next_in = compressedBytecode.begin() +
|
||||
mRequest->mBytecodeOffset + PREFIX_BYTES,
|
||||
.avail_in = static_cast<uint32_t>(
|
||||
compressedBytecode.length() -
|
||||
mRequest->mBytecodeOffset - PREFIX_BYTES),
|
||||
.next_out = mRequest->mScriptBytecode.begin() +
|
||||
mRequest->mBytecodeOffset,
|
||||
.avail_out = uncompressedLength};
|
||||
if (inflateInit(&zstream) != Z_OK) {
|
||||
LOG(("ScriptLoadRequest (%p): inflateInit FAILED (%s)",
|
||||
mRequest.get(), zstream.msg));
|
||||
return nsresult::NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
auto autoDestroy = MakeScopeExit([&]() { inflateEnd(&zstream); });
|
||||
|
||||
int ret = inflate(&zstream, Z_NO_FLUSH);
|
||||
bool ok = (ret == Z_OK || ret == Z_STREAM_END) && zstream.avail_in == 0;
|
||||
if (!ok) {
|
||||
LOG(("ScriptLoadRequest (%p): inflate FAILED (%s)", mRequest.get(),
|
||||
zstream.msg));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
Vector<uint8_t> compressedBytecode;
|
||||
// mRequest has the compressed bytecode, but will be filled with the
|
||||
// uncompressed bytecode
|
||||
compressedBytecode.swap(mRequest->mScriptBytecode);
|
||||
if (!JS::loader::ScriptBytecodeDecompress(compressedBytecode,
|
||||
mRequest->mBytecodeOffset,
|
||||
mRequest->mScriptBytecode)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user