#include "content/services/auction_worklet/auction_v8_helper.h"
#include <limits>
#include <memory>
#include <string_view>
#include <utility>
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/thread_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/services/auction_worklet/auction_v8_devtools_agent.h"
#include "content/services/auction_worklet/debug_command_queue.h"
#include "gin/array_buffer.h"
#include "gin/converter.h"
#include "gin/gin_features.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "v8/include/v8-context.h"
#include "v8/include/v8-exception.h"
#include "v8/include/v8-function.h"
#include "v8/include/v8-inspector.h"
#include "v8/include/v8-json.h"
#include "v8/include/v8-message.h"
#include "v8/include/v8-object.h"
#include "v8/include/v8-primitive.h"
#include "v8/include/v8-script.h"
#include "v8/include/v8-template.h"
#include "v8/include/v8-value-serializer.h"
#include "v8/include/v8-wasm.h"
namespace auction_worklet {
namespace {
void InitV8() { … }
class DebugContextScope { … };
void TraceTopLevel(const std::string& url,
perfetto::TracedValue trace_context) { … }
class TrivialSerializerDelegate : public v8::ValueSerializer::Delegate { … };
}
AuctionV8Helper::TimeLimit::~TimeLimit() = default;
AuctionV8Helper::TimeLimitScope::TimeLimitScope(TimeLimit* script_timeout)
: … { … }
AuctionV8Helper::TimeLimitScope::~TimeLimitScope() { … }
class AuctionV8Helper::ScriptTimeoutHelper : public AuctionV8Helper::TimeLimit { … };
constexpr base::TimeDelta AuctionV8Helper::kScriptTimeout = …base::Milliseconds(500);
#else
base::Milliseconds(50);
#endif
AuctionV8Helper::FullIsolateScope::FullIsolateScope(AuctionV8Helper* v8_helper)
: … { … }
AuctionV8Helper::FullIsolateScope::~FullIsolateScope() = default;
AuctionV8Helper::DebugId::DebugId(AuctionV8Helper* v8_helper)
: … { … }
void AuctionV8Helper::DebugId::SetResumeCallback(
base::OnceClosure resume_callback) { … }
void AuctionV8Helper::DebugId::AbortDebuggerPauses() { … }
AuctionV8Helper::DebugId::~DebugId() { … }
AuctionV8Helper::SerializedValue::SerializedValue()
: … { … }
AuctionV8Helper::SerializedValue::SerializedValue(SerializedValue&& other) { … }
AuctionV8Helper::SerializedValue::~SerializedValue() { … }
AuctionV8Helper::SerializedValue& AuctionV8Helper::SerializedValue::operator=(
SerializedValue&& other) { … }
scoped_refptr<AuctionV8Helper> AuctionV8Helper::Create(
scoped_refptr<base::SingleThreadTaskRunner> v8_runner) { … }
scoped_refptr<base::SingleThreadTaskRunner>
AuctionV8Helper::CreateTaskRunner() { … }
void AuctionV8Helper::SetDestroyedCallback(base::OnceClosure callback) { … }
v8::Local<v8::Context> AuctionV8Helper::CreateContext(
v8::Handle<v8::ObjectTemplate> global_template) { … }
v8::Local<v8::String> AuctionV8Helper::CreateStringFromLiteral(
const char* ascii_string) { … }
v8::MaybeLocal<v8::String> AuctionV8Helper::CreateUtf8String(
std::string_view utf8_string) { … }
v8::MaybeLocal<v8::Value> AuctionV8Helper::CreateValueFromJson(
v8::Local<v8::Context> context,
std::string_view utf8_json) { … }
bool AuctionV8Helper::AppendUtf8StringValue(std::string_view utf8_string,
v8::LocalVector<v8::Value>* args) { … }
bool AuctionV8Helper::AppendJsonValue(v8::Local<v8::Context> context,
std::string_view utf8_json,
v8::LocalVector<v8::Value>* args) { … }
bool AuctionV8Helper::InsertValue(std::string_view key,
v8::Local<v8::Value> value,
v8::Local<v8::Object> object) { … }
bool AuctionV8Helper::InsertJsonValue(v8::Local<v8::Context> context,
std::string_view key,
std::string_view utf8_json,
v8::Local<v8::Object> object) { … }
AuctionV8Helper::Result AuctionV8Helper::ExtractJson(
v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
TimeLimit* script_timeout,
std::string* out) { … }
AuctionV8Helper::SerializedValue AuctionV8Helper::Serialize(
v8::Local<v8::Context> context,
v8::Local<v8::Value> value) { … }
v8::MaybeLocal<v8::Value> AuctionV8Helper::Deserialize(
v8::Local<v8::Context> context,
const SerializedValue& serialized_value) { … }
v8::MaybeLocal<v8::UnboundScript> AuctionV8Helper::Compile(
const std::string& src,
const GURL& src_url,
const DebugId* debug_id,
std::optional<std::string>& error_out) { … }
v8::MaybeLocal<v8::WasmModuleObject> AuctionV8Helper::CompileWasm(
const std::string& payload,
const GURL& src_url,
const DebugId* debug_id,
std::optional<std::string>& error_out) { … }
v8::MaybeLocal<v8::WasmModuleObject> AuctionV8Helper::CloneWasmModule(
v8::Local<v8::WasmModuleObject> in) { … }
std::unique_ptr<AuctionV8Helper::TimeLimit> AuctionV8Helper::CreateTimeLimit(
std::optional<base::TimeDelta> script_timeout) { … }
AuctionV8Helper::TimeLimit* AuctionV8Helper::GetTimeLimit() { … }
AuctionV8Helper::Result AuctionV8Helper::RunScript(
v8::Local<v8::Context> context,
v8::Local<v8::UnboundScript> script,
const DebugId* debug_id,
TimeLimit* script_timeout,
std::vector<std::string>& error_out) { … }
AuctionV8Helper::Result AuctionV8Helper::CallFunction(
v8::Local<v8::Context> context,
const DebugId* debug_id,
const std::string& script_name,
std::string_view function_name,
base::span<v8::Local<v8::Value>> args,
TimeLimit* script_timeout,
v8::MaybeLocal<v8::Value>& value_out,
std::vector<std::string>& error_out) { … }
void AuctionV8Helper::AbortDebuggerPauses(int context_group_id) { … }
void AuctionV8Helper::MaybeTriggerInstrumentationBreakpoint(
const DebugId& debug_id,
const std::string& name) { … }
void AuctionV8Helper::set_script_timeout_for_testing(
base::TimeDelta script_timeout) { … }
int AuctionV8Helper::AllocContextGroupId() { … }
void AuctionV8Helper::SetResumeCallback(int context_group_id,
base::OnceClosure resume_callback) { … }
void AuctionV8Helper::FreeContextGroupId(int context_group_id) { … }
void AuctionV8Helper::Resume(int context_group_id) { … }
void AuctionV8Helper::SetLastContextGroupIdForTesting(int new_last_id) { … }
void AuctionV8Helper::ResumeAllForTesting() { … }
void AuctionV8Helper::ConnectDevToolsAgent(
mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> agent,
scoped_refptr<base::SequencedTaskRunner> mojo_sequence,
const DebugId& debug_id) { … }
v8_inspector::V8Inspector* AuctionV8Helper::inspector() { … }
void AuctionV8Helper::SetV8InspectorForTesting(
std::unique_ptr<v8_inspector::V8Inspector> v8_inspector) { … }
void AuctionV8Helper::PauseTimeoutTimer() { … }
void AuctionV8Helper::ResumeTimeoutTimer() { … }
scoped_refptr<base::SequencedTaskRunner>
AuctionV8Helper::GetTimeoutTimerRunnerForTesting() { … }
std::string AuctionV8Helper::FormatScriptName(
v8::Local<v8::UnboundScript> script) { … }
AuctionV8Helper::AuctionV8Helper(
scoped_refptr<base::SingleThreadTaskRunner> v8_runner)
: … { … }
AuctionV8Helper::~AuctionV8Helper() { … }
void AuctionV8Helper::CreateIsolate() { … }
std::string AuctionV8Helper::FormatExceptionMessage(
v8::Local<v8::Context> context,
v8::Local<v8::Message> message) { … }
std::string AuctionV8Helper::FormatValue(v8::Isolate* isolate,
v8::Local<v8::Value> val) { … }
}