Commit 56065148 authored by Dominic Cooney's avatar Dominic Cooney Committed by Commit Bot

Reuse the TryCatch scope whe retrieving custom element properties.

Defining a custom element retrieves various properties. Previously
each retrieval used a separate TryCatch, which turns out to be
expensive. This makes them reuse a single TryCatch.

Bug: 710184
Change-Id: Ieadd5ba9c9197fd4a4a0b6b1faf3861d1df53f3b
Reviewed-on: https://chromium-review.googlesource.com/520962Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Dominic Cooney <dominicc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#476542}
parent 53102380
......@@ -56,23 +56,27 @@ bool ScriptCustomElementDefinitionBuilder::CheckConstructorNotRegistered() {
}
bool ScriptCustomElementDefinitionBuilder::ValueForName(
v8::Isolate* isolate,
v8::Local<v8::Context>& context,
const v8::TryCatch& try_catch,
const v8::Local<v8::Object>& object,
const StringView& name,
v8::Local<v8::Value>& value) const {
v8::Isolate* isolate = script_state_->GetIsolate();
v8::Local<v8::Context> context = script_state_->GetContext();
v8::Local<v8::String> name_string = V8AtomicString(isolate, name);
v8::TryCatch try_catch(isolate);
if (!object->Get(context, name_string).ToLocal(&value)) {
exception_state_.RethrowV8Exception(try_catch.Exception());
return false;
}
return true;
return script_state_->ContextIsValid();
}
bool ScriptCustomElementDefinitionBuilder::CheckPrototype() {
v8::Isolate* isolate = script_state_->GetIsolate();
v8::Local<v8::Context> context = script_state_->GetContext();
v8::TryCatch try_catch(isolate);
v8::Local<v8::Value> prototype_value;
if (!ValueForName(constructor_, "prototype", prototype_value))
if (!ValueForName(isolate, context, try_catch, constructor_, "prototype",
prototype_value))
return false;
if (!prototype_value->IsObject()) {
exception_state_.ThrowTypeError("constructor prototype is not an object");
......@@ -85,10 +89,13 @@ bool ScriptCustomElementDefinitionBuilder::CheckPrototype() {
}
bool ScriptCustomElementDefinitionBuilder::CallableForName(
v8::Isolate* isolate,
v8::Local<v8::Context>& context,
const v8::TryCatch& try_catch,
const StringView& name,
v8::Local<v8::Function>& callback) const {
v8::Local<v8::Value> value;
if (!ValueForName(prototype_, name, value))
if (!ValueForName(isolate, context, try_catch, prototype_, name, value))
return false;
// "undefined" means "omitted", which is valid.
if (value->IsUndefined())
......@@ -102,16 +109,19 @@ bool ScriptCustomElementDefinitionBuilder::CallableForName(
return true;
}
bool ScriptCustomElementDefinitionBuilder::RetrieveObservedAttributes() {
bool ScriptCustomElementDefinitionBuilder::RetrieveObservedAttributes(
v8::Isolate* isolate,
v8::Local<v8::Context>& context,
const v8::TryCatch& try_catch) {
v8::Local<v8::Value> observed_attributes_value;
if (!ValueForName(constructor_, "observedAttributes",
observed_attributes_value))
if (!ValueForName(isolate, context, try_catch, constructor_,
"observedAttributes", observed_attributes_value))
return false;
if (observed_attributes_value->IsUndefined())
return true;
Vector<String> list = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(
script_state_->GetIsolate(), observed_attributes_value, exception_state_);
if (exception_state_.HadException())
isolate, observed_attributes_value, exception_state_);
if (exception_state_.HadException() || !script_state_->ContextIsValid())
return false;
if (list.IsEmpty())
return true;
......@@ -124,13 +134,20 @@ bool ScriptCustomElementDefinitionBuilder::RetrieveObservedAttributes() {
bool ScriptCustomElementDefinitionBuilder::RememberOriginalProperties() {
// Spec requires to use values of these properties at the point
// CustomElementDefinition is built, even if JS changes them afterwards.
return CallableForName("connectedCallback", connected_callback_) &&
CallableForName("disconnectedCallback", disconnected_callback_) &&
CallableForName("adoptedCallback", adopted_callback_) &&
CallableForName("attributeChangedCallback",
v8::Isolate* isolate = script_state_->GetIsolate();
v8::Local<v8::Context> context = script_state_->GetContext();
v8::TryCatch try_catch(isolate);
return CallableForName(isolate, context, try_catch, "connectedCallback",
connected_callback_) &&
CallableForName(isolate, context, try_catch, "disconnectedCallback",
disconnected_callback_) &&
CallableForName(isolate, context, try_catch, "adoptedCallback",
adopted_callback_) &&
CallableForName(isolate, context, try_catch,
"attributeChangedCallback",
attribute_changed_callback_) &&
(attribute_changed_callback_.IsEmpty() ||
RetrieveObservedAttributes());
RetrieveObservedAttributes(isolate, context, try_catch));
}
CustomElementDefinition* ScriptCustomElementDefinitionBuilder::Build(
......
......@@ -59,11 +59,20 @@ class CORE_EXPORT ScriptCustomElementDefinitionBuilder
HashSet<AtomicString> observed_attributes_;
ExceptionState& exception_state_;
bool ValueForName(const v8::Local<v8::Object>&,
bool ValueForName(v8::Isolate*,
v8::Local<v8::Context>&,
const v8::TryCatch&,
const v8::Local<v8::Object>&,
const StringView&,
v8::Local<v8::Value>&) const;
bool CallableForName(const StringView&, v8::Local<v8::Function>&) const;
bool RetrieveObservedAttributes();
bool CallableForName(v8::Isolate*,
v8::Local<v8::Context>&,
const v8::TryCatch&,
const StringView&,
v8::Local<v8::Function>&) const;
bool RetrieveObservedAttributes(v8::Isolate*,
v8::Local<v8::Context>&,
const v8::TryCatch&);
};
} // namespace blink
......
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