blob: 9cee156712a458e74f87814fced13aadca3d9519 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
namespace blink {
namespace bindings {
v8::MaybeLocal<v8::Function> GetCrossOriginFunction(
v8::Isolate* isolate,
v8::FunctionCallback callback,
int func_length,
const WrapperTypeInfo* wrapper_type_info) {
v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
ScriptState* script_state = ScriptState::From(current_context);
V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate);
const void* callback_key = reinterpret_cast<const void*>(callback);
v8::Local<v8::FunctionTemplate> function_template =
per_isolate_data->FindV8Template(script_state->World(), callback_key)
.As<v8::FunctionTemplate>();
if (function_template.IsEmpty()) {
v8::Local<v8::FunctionTemplate> interface_template =
per_isolate_data
->FindV8Template(script_state->World(), wrapper_type_info)
.As<v8::FunctionTemplate>();
v8::Local<v8::Signature> signature =
v8::Signature::New(isolate, interface_template);
function_template = v8::FunctionTemplate::New(
isolate, callback, v8::Local<v8::Value>(), signature, func_length,
v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasSideEffect);
per_isolate_data->AddV8Template(script_state->World(), callback_key,
function_template);
}
return function_template->GetFunction(current_context);
}
v8::MaybeLocal<v8::Value> GetCrossOriginFunctionOrUndefined(
v8::Isolate* isolate,
v8::FunctionCallback callback,
int func_length,
const WrapperTypeInfo* wrapper_type_info) {
if (!callback) {
return v8::Undefined(isolate);
}
v8::Local<v8::Function> function;
if (GetCrossOriginFunction(isolate, callback, func_length, wrapper_type_info)
.ToLocal(&function)) {
return function;
}
return v8::MaybeLocal<v8::Value>();
}
bool IsSupportedInCrossOriginPropertyFallback(
v8::Isolate* isolate,
v8::Local<v8::Name> property_name) {
return (property_name == V8AtomicString(isolate, "then") ||
property_name == v8::Symbol::GetToStringTag(isolate) ||
property_name == v8::Symbol::GetHasInstance(isolate) ||
property_name == v8::Symbol::GetIsConcatSpreadable(isolate));
}
v8::Local<v8::Array> EnumerateCrossOriginProperties(
v8::Isolate* isolate,
base::span<const CrossOriginAttributeTableEntry> attributes,
base::span<const CrossOriginOperationTableEntry> operations) {
v8::Local<v8::Value> default_supported[] = {
V8AtomicString(isolate, "then"),
v8::Symbol::GetToStringTag(isolate),
v8::Symbol::GetHasInstance(isolate),
v8::Symbol::GetIsConcatSpreadable(isolate),
};
const uint32_t length =
attributes.size() + operations.size() + base::size(default_supported);
Vector<v8::Local<v8::Value>> elements;
elements.ReserveCapacity(length);
for (const auto& attribute : attributes)
elements.UncheckedAppend(V8AtomicString(isolate, attribute.name));
for (const auto& operation : operations)
elements.UncheckedAppend(V8AtomicString(isolate, operation.name));
for (const auto& name : default_supported)
elements.UncheckedAppend(name);
return v8::Array::New(isolate, elements.data(), elements.size());
}
} // namespace bindings
} // namespace blink