#include "isolate/run_with_timeout.h" #include "isolate/three_phase_task.h" #include "context_handle.h" #include "script_handle.h" using namespace v8; namespace ivm { /** * ScriptHandle implementation */ ScriptHandle::ScriptHandle(RemoteHandle script) : script{std::move(script)} {} auto ScriptHandle::Definition() -> Local { return Inherit(MakeClass( "Script", nullptr, "release", MemberFunction{}, "run", MemberFunction), &ScriptHandle::Run<1>>{}, "runIgnored", MemberFunction), &ScriptHandle::Run<2>>{}, "runSync", MemberFunction), &ScriptHandle::Run<0>>{} )); } auto ScriptHandle::TransferOut() -> std::unique_ptr { return std::make_unique(script); } auto ScriptHandle::Release() -> Local { script = {}; return Undefined(Isolate::GetCurrent()); } /* * Run this script in a given context */ struct RunRunner /* lol */ : public ThreePhaseTask { RunRunner( RemoteHandle& script, ContextHandle& context_handle, MaybeLocal maybe_options ) : context{context_handle.GetContext()} { // Sanity check if (!script) { throw RuntimeGenericError("Script has been released"); } if (script.GetIsolateHolder() != context.GetIsolateHolder()) { throw RuntimeGenericError("Invalid context"); } // Parse options bool release = false; Local options; if (maybe_options.ToLocal(&options)) { release = ReadOption(options, StringTable::Get().release, false); timeout_ms = ReadOption(options, StringTable::Get().timeout, 0); } if (release) { this->script = std::move(script); } else { this->script = script; } transfer_options = TransferOptions{maybe_options}; } void Phase2() final { // Enter script's context and run it Local context_local = Deref(context); Context::Scope context_scope{context_local}; Local