Commit 2b3df06b authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[api] Change host-defined options to v8::Data

In the future we will allow arbitrary objects as host-defined options.
To prepare the embedders for the upcoming changes we migrate the API
to use v8::Data where possible.

Internally we still use i::FixedArray with primitive values until the
migration to context-stored host-defined options is completed.

Note: This CL also introduces a temporary cast and inheritance
between Data and PrimitiveArray which will be removed again.

Bug: chromium:1244145
Change-Id: I852d0d827708d32b6f3a6d03457234a006e2fd77
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3264285
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77795}
parent 947138fe
......@@ -70,24 +70,26 @@ class V8_EXPORT ScriptOrigin {
Local<Boolean> resource_is_opaque = Local<Boolean>(),
Local<Boolean> is_wasm = Local<Boolean>(),
Local<Boolean> is_module = Local<Boolean>(),
Local<PrimitiveArray> host_defined_options = Local<PrimitiveArray>());
Local<Data> host_defined_options = Local<Data>());
V8_DEPRECATED("Use constructor that takes an isolate")
explicit ScriptOrigin(
Local<Value> resource_name, int resource_line_offset = 0,
int resource_column_offset = 0,
bool resource_is_shared_cross_origin = false, int script_id = -1,
Local<Value> source_map_url = Local<Value>(),
bool resource_is_opaque = false, bool is_wasm = false,
bool is_module = false,
Local<PrimitiveArray> host_defined_options = Local<PrimitiveArray>());
V8_INLINE ScriptOrigin(
Isolate* isolate, Local<Value> resource_name,
int resource_line_offset = 0, int resource_column_offset = 0,
bool resource_is_shared_cross_origin = false, int script_id = -1,
Local<Value> source_map_url = Local<Value>(),
bool resource_is_opaque = false, bool is_wasm = false,
bool is_module = false,
Local<PrimitiveArray> host_defined_options = Local<PrimitiveArray>())
explicit ScriptOrigin(Local<Value> resource_name,
int resource_line_offset = 0,
int resource_column_offset = 0,
bool resource_is_shared_cross_origin = false,
int script_id = -1,
Local<Value> source_map_url = Local<Value>(),
bool resource_is_opaque = false, bool is_wasm = false,
bool is_module = false,
Local<Data> host_defined_options = Local<Data>());
V8_INLINE ScriptOrigin(Isolate* isolate, Local<Value> resource_name,
int resource_line_offset = 0,
int resource_column_offset = 0,
bool resource_is_shared_cross_origin = false,
int script_id = -1,
Local<Value> source_map_url = Local<Value>(),
bool resource_is_opaque = false, bool is_wasm = false,
bool is_module = false,
Local<Data> host_defined_options = Local<Data>())
: isolate_(isolate),
resource_name_(resource_name),
resource_line_offset_(resource_line_offset),
......@@ -96,7 +98,9 @@ class V8_EXPORT ScriptOrigin {
is_module),
script_id_(script_id),
source_map_url_(source_map_url),
host_defined_options_(host_defined_options) {}
host_defined_options_(host_defined_options) {
VerifyHostDefinedOptions();
}
V8_INLINE Local<Value> ResourceName() const;
V8_DEPRECATED("Use getter with primitive C++ types.")
......@@ -109,10 +113,13 @@ class V8_EXPORT ScriptOrigin {
V8_INLINE int ColumnOffset() const;
V8_INLINE int ScriptId() const;
V8_INLINE Local<Value> SourceMapUrl() const;
V8_INLINE Local<PrimitiveArray> HostDefinedOptions() const;
V8_DEPRECATE_SOON("Use GetHostDefinedOptions")
Local<PrimitiveArray> HostDefinedOptions() const;
V8_INLINE Local<Data> GetHostDefinedOptions() const;
V8_INLINE ScriptOriginOptions Options() const { return options_; }
private:
void VerifyHostDefinedOptions() const;
Isolate* isolate_;
Local<Value> resource_name_;
int resource_line_offset_;
......@@ -120,7 +127,7 @@ class V8_EXPORT ScriptOrigin {
ScriptOriginOptions options_;
int script_id_;
Local<Value> source_map_url_;
Local<PrimitiveArray> host_defined_options_;
Local<Data> host_defined_options_;
};
/**
......@@ -220,7 +227,7 @@ class V8_EXPORT Message {
Local<Value> ScriptOrigin::ResourceName() const { return resource_name_; }
Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
Local<Data> ScriptOrigin::GetHostDefinedOptions() const {
return host_defined_options_;
}
......
......@@ -54,12 +54,22 @@ class V8_EXPORT Boolean : public Primitive {
* This is passed back to the embedder as part of
* HostImportModuleDynamicallyCallback for module loading.
*/
class V8_EXPORT PrimitiveArray {
class V8_EXPORT PrimitiveArray : public Data {
public:
static Local<PrimitiveArray> New(Isolate* isolate, int length);
int Length() const;
void Set(Isolate* isolate, int index, Local<Primitive> item);
Local<Primitive> Get(Isolate* isolate, int index);
V8_INLINE static PrimitiveArray* Cast(Data* data) {
#ifdef V8_ENABLE_CHECKS
CheckCast(data);
#endif
return reinterpret_cast<PrimitiveArray*>(data);
}
private:
static void CheckCast(Data* obj);
};
/**
......
......@@ -47,7 +47,9 @@ class V8_EXPORT ScriptOrModule {
* The options that were passed by the embedder as HostDefinedOptions to
* the ScriptOrigin.
*/
V8_DEPRECATE_SOON("Use HostDefinedOptions")
Local<PrimitiveArray> GetHostDefinedOptions();
Local<Data> HostDefinedOptions();
};
/**
......@@ -432,7 +434,7 @@ class V8_EXPORT ScriptCompiler {
int resource_column_offset;
ScriptOriginOptions resource_options;
Local<Value> source_map_url;
Local<PrimitiveArray> host_defined_options;
Local<Data> host_defined_options;
// Cached data from previous compilation (if a kConsume*Cache flag is
// set), or hold newly generated cache data (kProduce*Cache flags) are
......@@ -750,7 +752,7 @@ ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
resource_column_offset(origin.ColumnOffset()),
resource_options(origin.Options()),
source_map_url(origin.SourceMapUrl()),
host_defined_options(origin.HostDefinedOptions()),
host_defined_options(origin.GetHostDefinedOptions()),
cached_data(data),
consume_cache_task(consume_cache_task) {}
......
......@@ -171,8 +171,8 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
i::Handle<i::Script> script) {
i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(),
isolate);
i::Handle<i::Object> host_defined_options(script->host_defined_options(),
isolate);
ScriptOriginOptions options(script->origin_options());
bool is_wasm = false;
#if V8_ENABLE_WEBASSEMBLY
......@@ -183,7 +183,7 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
script->line_offset(), script->column_offset(),
options.IsSharedCrossOrigin(), script->id(),
Utils::ToLocal(source_map_url), options.IsOpaque(), is_wasm,
options.IsModule(), Utils::PrimitiveArrayToLocal(host_defined_options));
options.IsModule(), Utils::ToLocal(host_defined_options));
return origin;
}
......@@ -192,7 +192,7 @@ ScriptOrigin::ScriptOrigin(
Local<Integer> column_offset, Local<Boolean> is_shared_cross_origin,
Local<Integer> script_id, Local<Value> source_map_url,
Local<Boolean> is_opaque, Local<Boolean> is_wasm, Local<Boolean> is_module,
Local<PrimitiveArray> host_defined_options)
Local<Data> host_defined_options)
: ScriptOrigin(
Isolate::GetCurrent(), resource_name,
line_offset.IsEmpty() ? 0 : static_cast<int>(line_offset->Value()),
......@@ -208,7 +208,7 @@ ScriptOrigin::ScriptOrigin(Local<Value> resource_name, int line_offset,
int column_offset, bool is_shared_cross_origin,
int script_id, Local<Value> source_map_url,
bool is_opaque, bool is_wasm, bool is_module,
Local<PrimitiveArray> host_defined_options)
Local<Data> host_defined_options)
: isolate_(Isolate::GetCurrent()),
resource_name_(resource_name),
resource_line_offset_(line_offset),
......@@ -230,6 +230,17 @@ Local<Integer> ScriptOrigin::ScriptID() const {
return v8::Integer::New(isolate_, script_id_);
}
Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
// TODO(cbruni, chromium:1244145): remove once migrated to the context.
Utils::ApiCheck(!host_defined_options_->IsFixedArray(),
"ScriptOrigin::HostDefinedOptions",
"HostDefinedOptions is not a PrimitiveArray, please use "
"ScriptOrigin::GetHostDefinedOptions()");
i::Handle<i::FixedArray> options =
Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
return Utils::PrimitiveArrayToLocal(options);
}
// --- E x c e p t i o n B e h a v i o r ---
void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
......@@ -2106,7 +2117,7 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
i::Handle<i::Object> receiver = isolate->global_proxy();
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
i::Handle<i::FixedArray> options(
i::Handle<i::Object> options(
i::Script::cast(fun->shared().script()).host_defined_options(), isolate);
Local<Value> result;
has_pending_exception = !ToLocal<Value>(
......@@ -2134,11 +2145,15 @@ Local<Value> ScriptOrModule::GetResourceName() {
}
Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
return HostDefinedOptions().As<PrimitiveArray>();
}
Local<Data> ScriptOrModule::HostDefinedOptions() {
i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::Handle<i::FixedArray> val(obj->host_defined_options(), isolate);
return ToApiHandle<PrimitiveArray>(val);
i::Handle<i::Object> val(obj->host_defined_options(), isolate);
return ToApiHandle<Data>(val);
}
Local<UnboundScript> Script::GetUnboundScript() {
......@@ -2199,6 +2214,14 @@ Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
return ToApiHandle<Primitive>(i_item);
}
void v8::PrimitiveArray::CheckCast(v8::Data* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
Utils::ApiCheck(
obj->IsFixedArray(), "v8::PrimitiveArray::Cast",
"Value is not a PrimitiveArray. This is a temporary issue, v8::Data and "
"v8::PrimitiveArray will not be compatible in the future.");
}
int FixedArray::Length() const {
i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
return self->length();
......@@ -2478,13 +2501,10 @@ Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
namespace {
i::ScriptDetails GetScriptDetails(i::Isolate* isolate,
Local<Value> resource_name,
int resource_line_offset,
int resource_column_offset,
Local<Value> source_map_url,
Local<PrimitiveArray> host_defined_options,
ScriptOriginOptions origin_options) {
i::ScriptDetails GetScriptDetails(
i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset,
int resource_column_offset, Local<Value> source_map_url,
Local<Data> host_defined_options, ScriptOriginOptions origin_options) {
i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
origin_options);
script_details.line_offset = resource_line_offset;
......@@ -2776,7 +2796,7 @@ i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
i::ScriptDetails script_details =
GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
origin.ColumnOffset(), origin.SourceMapUrl(),
origin.HostDefinedOptions(), origin.Options());
origin.GetHostDefinedOptions(), origin.Options());
i::ScriptStreamingData* data = v8_source->impl();
return i::Compiler::GetSharedFunctionInfoForStreamedScript(
isolate, str, script_details, data);
......@@ -3030,6 +3050,20 @@ ScriptOrigin Message::GetScriptOrigin() const {
return GetScriptOriginForScript(isolate, script);
}
void ScriptOrigin::VerifyHostDefinedOptions() const {
// TODO(cbruni, chromium:1244145): Remove checks once we allow arbitrary
// host-defined options.
if (host_defined_options_.IsEmpty()) return;
Utils::ApiCheck(host_defined_options_->IsFixedArray(), "ScriptOrigin()",
"Host-defined options has to be a PrimitiveArray");
i::Handle<i::FixedArray> options =
Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
for (int i = 0; i < options->length(); i++) {
Utils::ApiCheck(options->get(i).IsPrimitive(), "ScriptOrigin()",
"PrimitiveArray can only contain primtive values");
}
}
v8::Local<Value> Message::GetScriptResourceName() const {
ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
return GetScriptOrigin().ResourceName();
......
......@@ -136,12 +136,16 @@ bool HasOrigin(Isolate* isolate, Handle<SharedFunctionInfo> function_info,
return false;
}
Handle<FixedArray> host_defined_options;
if (!script_details.host_defined_options.ToHandle(&host_defined_options)) {
host_defined_options = isolate->factory()->empty_fixed_array();
// TODO(cbruni, chromium:1244145): Remove once migrated to the context
Handle<Object> maybe_host_defined_options;
if (!script_details.host_defined_options.ToHandle(
&maybe_host_defined_options)) {
maybe_host_defined_options = isolate->factory()->empty_fixed_array();
}
Handle<FixedArray> script_options(script->host_defined_options(), isolate);
Handle<FixedArray> host_defined_options =
Handle<FixedArray>::cast(maybe_host_defined_options);
Handle<FixedArray> script_options(
FixedArray::cast(script->host_defined_options()), isolate);
int length = host_defined_options->length();
if (length != script_options->length()) return false;
......
......@@ -1465,9 +1465,12 @@ void SetScriptFieldsFromDetails(Isolate* isolate, Script script,
script.source_mapping_url(isolate).IsUndefined(isolate)) {
script.set_source_mapping_url(*source_map_url);
}
Handle<FixedArray> host_defined_options;
Handle<Object> host_defined_options;
if (script_details.host_defined_options.ToHandle(&host_defined_options)) {
script.set_host_defined_options(*host_defined_options);
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
if (host_defined_options->IsFixedArray()) {
script.set_host_defined_options(FixedArray::cast(*host_defined_options));
}
}
}
......
......@@ -29,7 +29,7 @@ struct ScriptDetails {
int column_offset;
MaybeHandle<Object> name_obj;
MaybeHandle<Object> source_map_url;
MaybeHandle<FixedArray> host_defined_options;
MaybeHandle<Object> host_defined_options;
REPLMode repl_mode;
const ScriptOriginOptions origin_options;
};
......
......@@ -762,8 +762,8 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
i::Script::cast(Utils::OpenHandle(*script)->shared().script()),
i_isolate);
// TODO(cbruni, chromium:1244145): remove once context-allocated.
i_script->set_host_defined_options(
*Utils::OpenHandle(*(origin.HostDefinedOptions())));
i_script->set_host_defined_options(i::FixedArray::cast(
*Utils::OpenHandle(*(origin.GetHostDefinedOptions()))));
}
maybe_result = script->Run(realm);
if (options.code_cache_options ==
......
......@@ -519,14 +519,15 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
}
// static
MaybeHandle<Object> Execution::CallScript(
Isolate* isolate, Handle<JSFunction> script_function,
Handle<Object> receiver, Handle<FixedArray> host_defined_options) {
MaybeHandle<Object> Execution::CallScript(Isolate* isolate,
Handle<JSFunction> script_function,
Handle<Object> receiver,
Handle<Object> host_defined_options) {
DCHECK(script_function->shared().is_script());
DCHECK(receiver->IsJSGlobalProxy() || receiver->IsJSGlobalObject());
Handle<Object> argument = host_defined_options;
return Invoke(isolate, InvokeParams::SetUpForCall(isolate, script_function,
receiver, 1, &argument));
return Invoke(
isolate, InvokeParams::SetUpForCall(isolate, script_function, receiver, 1,
&host_defined_options));
}
MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
......
......@@ -33,7 +33,7 @@ class Execution final : public AllStatic {
// caller has to provide it at all times.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object> CallScript(
Isolate* isolate, Handle<JSFunction> callable, Handle<Object> receiver,
Handle<FixedArray> host_defined_options);
Handle<Object> host_defined_options);
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> CallBuiltin(
Isolate* isolate, Handle<JSFunction> builtin, Handle<Object> receiver,
......
......@@ -17449,7 +17449,10 @@ THREADED_TEST(ScriptOrigin) {
CHECK(script_origin_f.Options().IsSharedCrossOrigin());
CHECK(script_origin_f.Options().IsOpaque());
printf("is name = %d\n", script_origin_f.SourceMapUrl()->IsUndefined());
CHECK(script_origin_f.HostDefinedOptions()->Get(isolate, 0)->IsSymbol());
CHECK(script_origin_f.GetHostDefinedOptions()
.As<v8::PrimitiveArray>()
->Get(isolate, 0)
->IsSymbol());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(env->GetIsolate(),
......@@ -17465,7 +17468,10 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(env->GetIsolate(),
script_origin_g.SourceMapUrl())));
CHECK(script_origin_g.HostDefinedOptions()->Get(isolate, 0)->IsSymbol());
CHECK(script_origin_g.GetHostDefinedOptions()
.As<v8::PrimitiveArray>()
->Get(isolate, 0)
->IsSymbol());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment