WasmStreamingParser.h [plain text]
#pragma once
#if ENABLE(WEBASSEMBLY)
#include "WasmModuleInformation.h"
#include "WasmParser.h"
#include "WasmSections.h"
#include <wtf/CrossThreadCopier.h>
#include <wtf/SHA1.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace JSC { namespace Wasm {
class StreamingParserClient {
public:
virtual ~StreamingParserClient() = default;
virtual bool didReceiveSectionData(Section) { return true; };
virtual bool didReceiveFunctionData(unsigned, const FunctionData&) = 0;
virtual void didFinishParsing() { }
};
class StreamingParser {
WTF_MAKE_FAST_ALLOCATED;
public:
enum class State : uint8_t {
ModuleHeader,
SectionID,
SectionSize,
SectionPayload,
CodeSectionSize,
FunctionSize,
FunctionPayload,
Finished,
FatalError,
};
enum class IsEndOfStream { Yes, No };
StreamingParser(ModuleInformation&, StreamingParserClient&);
State addBytes(const uint8_t* bytes, size_t length) { return addBytes(bytes, length, IsEndOfStream::No); }
State finalize();
String errorMessage() const { return crossThreadCopy(m_errorMessage); }
void reportError() { moveToStateIfNotFailed(failOnState(State::FatalError)); }
private:
static constexpr unsigned moduleHeaderSize = 8;
static constexpr unsigned sectionIDSize = 1;
State addBytes(const uint8_t* bytes, size_t length, IsEndOfStream);
State parseModuleHeader(Vector<uint8_t>&&);
State parseSectionID(Vector<uint8_t>&&);
State parseSectionSize(uint32_t);
State parseSectionPayload(Vector<uint8_t>&&);
State parseCodeSectionSize(uint32_t);
State parseFunctionSize(uint32_t);
State parseFunctionPayload(Vector<uint8_t>&&);
Optional<Vector<uint8_t>> consume(const uint8_t* bytes, size_t, size_t&, size_t);
Expected<uint32_t, State> consumeVarUInt32(const uint8_t* bytes, size_t, size_t&, IsEndOfStream);
void moveToStateIfNotFailed(State);
template <typename ...Args> NEVER_INLINE State WARN_UNUSED_RETURN fail(Args...);
State failOnState(State);
Ref<ModuleInformation> m_info;
StreamingParserClient& m_client;
Vector<uint8_t> m_remaining;
String m_errorMessage;
CheckedSize m_totalSize { 0 };
size_t m_offset { 0 };
size_t m_nextOffset { 0 };
size_t m_codeOffset { 0 };
SHA1 m_hasher;
uint32_t m_sectionLength { 0 };
uint32_t m_functionCount { 0 };
uint32_t m_functionIndex { 0 };
uint32_t m_functionSize { 0 };
Lock m_stateLock;
State m_state { State::ModuleHeader };
Section m_section { Section::Begin };
Section m_previousKnownSection { Section::Begin };
};
} }
#endif // ENABLE(WEBASSEMBLY)