#pragma once
#if ENABLE(WEBASSEMBLY)
#include "CompilationResult.h"
#include "VM.h"
#include "WasmB3IRGenerator.h"
#include "WasmModuleInformation.h"
#include <wtf/Bag.h>
#include <wtf/SharedTask.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
namespace JSC {
class CallLinkInfo;
class JSGlobalObject;
class JSPromiseDeferred;
namespace Wasm {
class Plan : public ThreadSafeRefCounted<Plan> {
public:
typedef void CallbackType(VM*, Plan&);
using CompletionTask = RefPtr<SharedTask<CallbackType>>;
static CompletionTask dontFinalize() { return createSharedTask<CallbackType>([](VM*, Plan&) { }); }
Plan(VM*, Ref<ModuleInformation>, CompletionTask&&);
JS_EXPORT_PRIVATE Plan(VM*, const uint8_t*, size_t, CompletionTask&&);
virtual JS_EXPORT_PRIVATE ~Plan();
void addCompletionTask(VM&, CompletionTask&&);
void setMode(MemoryMode mode) { m_mode = mode; }
MemoryMode mode() const { return m_mode; }
const String& errorMessage() const { return m_errorMessage; }
bool WARN_UNUSED_RETURN failed() const { return !errorMessage().isNull(); }
virtual bool hasWork() const = 0;
enum CompilationEffort { All, Partial };
virtual void work(CompilationEffort = All) = 0;
virtual bool multiThreaded() const = 0;
void waitForCompletion();
bool tryRemoveVMAndCancelIfLast(VM&);
protected:
void runCompletionTasks(const AbstractLocker&);
void fail(const AbstractLocker&, String&& errorMessage);
virtual bool isComplete() const = 0;
virtual void complete(const AbstractLocker&) = 0;
Ref<ModuleInformation> m_moduleInformation;
Vector<std::pair<VM*, CompletionTask>, 1> m_completionTasks;
const uint8_t* m_source;
const size_t m_sourceLength;
String m_errorMessage;
MemoryMode m_mode { MemoryMode::BoundsChecking };
Lock m_lock;
Condition m_completed;
};
} }
#endif // ENABLE(WEBASSEMBLY)