Commit e64810b5 authored by dcarney's avatar dcarney Committed by Commit bot

cleanup api-natives a bit

R=verwaest@chromium.org

BUG=

Review URL: https://codereview.chromium.org/901923002

Cr-Commit-Position: refs/heads/master@{#26481}
parent 6efd03c4
......@@ -10,43 +10,71 @@ namespace internal {
namespace {
// Transform getter or setter into something DefineAccessor can handle.
Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
Handle<Object> component) {
if (component->IsUndefined()) return isolate->factory()->undefined_value();
Handle<FunctionTemplateInfo> info =
Handle<FunctionTemplateInfo>::cast(component);
// TODO(dcarney): instantiate directly.
return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
Handle<ObjectTemplateInfo> data);
MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
Handle<FunctionTemplateInfo> data,
Handle<Name> name = Handle<Name>());
MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
Handle<Name> name = Handle<Name>()) {
if (data->IsFunctionTemplateInfo()) {
return InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(data), name);
} else if (data->IsObjectTemplateInfo()) {
return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data));
} else {
return data;
}
}
MaybeHandle<Object> DefineApiAccessorProperty(
MaybeHandle<Object> DefineAccessorProperty(
Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
Handle<Object> getter, Handle<Object> setter, Smi* attribute) {
Handle<Object> getter, Handle<Object> setter, Smi* attributes) {
DCHECK(PropertyDetails::AttributesField::is_valid(
static_cast<PropertyAttributes>(attribute->value())));
RETURN_ON_EXCEPTION(
isolate, JSObject::DefineAccessor(
object, name, InstantiateAccessorComponent(isolate, getter),
InstantiateAccessorComponent(isolate, setter),
static_cast<PropertyAttributes>(attribute->value())),
Object);
static_cast<PropertyAttributes>(attributes->value())));
if (!getter->IsUndefined()) {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, getter,
InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(getter)),
Object);
}
if (!setter->IsUndefined()) {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, setter,
InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(setter)),
Object);
}
RETURN_ON_EXCEPTION(isolate,
JSObject::DefineAccessor(
object, name, getter, setter,
static_cast<PropertyAttributes>(attributes->value())),
Object);
return object;
}
MaybeHandle<Object> AddPropertyForTemplate(Isolate* isolate,
Handle<JSObject> object,
Handle<Object> key,
Handle<Object> value,
Smi* unchecked_attributes) {
MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
Handle<JSObject> object,
Handle<Name> key,
Handle<Object> prop_data,
Smi* unchecked_attributes) {
DCHECK((unchecked_attributes->value() &
~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
// Compute attributes.
PropertyAttributes attributes =
static_cast<PropertyAttributes>(unchecked_attributes->value());
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
Instantiate(isolate, prop_data, key), Object);
#ifdef DEBUG
bool duplicate;
if (key->IsName()) {
......@@ -95,29 +123,6 @@ void EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
}
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
Handle<ObjectTemplateInfo> data);
MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
Handle<FunctionTemplateInfo> data,
Handle<Name> name = Handle<Name>());
MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
Handle<Name> name = Handle<Name>()) {
if (data->IsFunctionTemplateInfo()) {
return InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(data), name);
} else if (data->IsObjectTemplateInfo()) {
return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data));
} else {
// TODO(dcarney): CHECK data is JSObject or Primitive.
return data;
}
}
class AccessCheckDisableScope {
public:
AccessCheckDisableScope(Isolate* isolate, Handle<JSObject> obj)
......@@ -157,23 +162,18 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
auto name = handle(Name::cast(properties.get(i + 1)), isolate);
auto prop_data = handle(properties.get(i + 2), isolate);
auto attributes = Smi::cast(properties.get(i + 3));
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, Instantiate(isolate, prop_data, name), JSObject);
RETURN_ON_EXCEPTION(isolate, AddPropertyForTemplate(isolate, obj, name,
value, attributes),
RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
prop_data, attributes),
JSObject);
} else {
DCHECK(length == 4 || length == 5);
// TODO(verwaest): The 5th value used to be access_control. Remove once
// the bindings are updated.
DCHECK(length == 4);
auto name = handle(Name::cast(properties.get(i + 1)), isolate);
auto getter = handle(properties.get(i + 2), isolate);
auto setter = handle(properties.get(i + 3), isolate);
auto attributes = Smi::cast(properties.get(i + 4));
RETURN_ON_EXCEPTION(isolate,
DefineApiAccessorProperty(isolate, obj, name, getter,
setter, attributes),
DefineAccessorProperty(isolate, obj, name, getter,
setter, attributes),
JSObject);
}
i += length + 1;
......@@ -313,6 +313,25 @@ class InvokeScope {
SaveContext save_context_;
};
void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
int length, Handle<Object>* data) {
auto list = handle(templ->property_list(), isolate);
if (list->IsUndefined()) {
list = NeanderArray(isolate).value();
templ->set_property_list(*list);
}
NeanderArray array(list);
array.add(isolate, isolate->factory()->NewNumberFromInt(length));
for (int i = 0; i < length; i++) {
Handle<Object> value =
data[i].is_null()
? Handle<Object>::cast(isolate->factory()->undefined_value())
: data[i];
array.add(isolate, value);
}
}
} // namespace
......@@ -348,6 +367,46 @@ MaybeHandle<FunctionTemplateInfo> ApiNatives::ConfigureInstance(
}
void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
Handle<Name> name, Handle<Object> value,
PropertyAttributes attributes) {
const int kSize = 3;
DCHECK(Smi::IsValid(static_cast<int>(attributes)));
auto attribute_handle =
handle(Smi::FromInt(static_cast<int>(attributes)), isolate);
Handle<Object> data[kSize] = {name, value, attribute_handle};
AddPropertyToPropertyList(isolate, info, kSize, data);
}
void ApiNatives::AddAccessorProperty(Isolate* isolate,
Handle<TemplateInfo> info,
Handle<Name> name,
Handle<FunctionTemplateInfo> getter,
Handle<FunctionTemplateInfo> setter,
PropertyAttributes attributes) {
const int kSize = 4;
DCHECK(Smi::IsValid(static_cast<int>(attributes)));
auto attribute_handle =
handle(Smi::FromInt(static_cast<int>(attributes)), isolate);
Handle<Object> data[kSize] = {name, getter, setter, attribute_handle};
AddPropertyToPropertyList(isolate, info, kSize, data);
}
void ApiNatives::AddNativeDataProperty(Isolate* isolate,
Handle<TemplateInfo> info,
Handle<AccessorInfo> property) {
auto list = handle(info->property_accessors(), isolate);
if (list->IsUndefined()) {
list = NeanderArray(isolate).value();
info->set_property_accessors(*list);
}
NeanderArray array(list);
array.add(isolate, property);
}
Handle<JSFunction> ApiNatives::CreateApiFunction(
Isolate* isolate, Handle<FunctionTemplateInfo> obj,
Handle<Object> prototype, ApiInstanceType instance_type) {
......
......@@ -14,8 +14,10 @@ class ApiNatives {
public:
MUST_USE_RESULT static MaybeHandle<JSFunction> InstantiateFunction(
Handle<FunctionTemplateInfo> data);
MUST_USE_RESULT static MaybeHandle<JSObject> InstantiateObject(
Handle<ObjectTemplateInfo> data);
MUST_USE_RESULT static MaybeHandle<FunctionTemplateInfo> ConfigureInstance(
Isolate* isolate, Handle<FunctionTemplateInfo> instance,
Handle<JSObject> data);
......@@ -30,6 +32,19 @@ class ApiNatives {
Handle<FunctionTemplateInfo> obj,
Handle<Object> prototype,
ApiInstanceType instance_type);
static void AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
Handle<Name> name, Handle<Object> value,
PropertyAttributes attributes);
static void AddAccessorProperty(Isolate* isolate, Handle<TemplateInfo> info,
Handle<Name> name,
Handle<FunctionTemplateInfo> getter,
Handle<FunctionTemplateInfo> setter,
PropertyAttributes attributes);
static void AddNativeDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
Handle<AccessorInfo> property);
};
} // namespace internal
......
......@@ -766,39 +766,17 @@ static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
}
static void TemplateSet(i::Isolate* isolate,
v8::Template* templ,
int length,
v8::Handle<v8::Data>* data) {
i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
if (list->IsUndefined()) {
list = NeanderArray(isolate).value();
Utils::OpenHandle(templ)->set_property_list(*list);
}
NeanderArray array(list);
array.add(isolate, isolate->factory()->NewNumberFromInt(length));
for (int i = 0; i < length; i++) {
i::Handle<i::Object> value = data[i].IsEmpty() ?
i::Handle<i::Object>(isolate->factory()->undefined_value()) :
Utils::OpenHandle(*data[i]);
array.add(isolate, value);
}
}
void Template::Set(v8::Handle<Name> name,
v8::Handle<Data> value,
v8::PropertyAttribute attribute) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
auto templ = Utils::OpenHandle(this);
i::Isolate* isolate = templ->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
const int kSize = 3;
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Handle<v8::Data> data[kSize] = {
name,
value,
v8::Integer::New(v8_isolate, attribute)};
TemplateSet(isolate, this, kSize, data);
// TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
Utils::OpenHandle(*value),
static_cast<PropertyAttributes>(attribute));
}
......@@ -810,19 +788,16 @@ void Template::SetAccessorProperty(
v8::AccessControl access_control) {
// TODO(verwaest): Remove |access_control|.
DCHECK_EQ(v8::DEFAULT, access_control);
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
auto templ = Utils::OpenHandle(this);
auto isolate = templ->GetIsolate();
ENTER_V8(isolate);
DCHECK(!name.IsEmpty());
DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
i::HandleScope scope(isolate);
const int kSize = 5;
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Handle<v8::Data> data[kSize] = {
name,
getter,
setter,
v8::Integer::New(v8_isolate, attribute)};
TemplateSet(isolate, this, kSize, data);
i::ApiNatives::AddAccessorProperty(
isolate, templ, Utils::OpenHandle(*name),
Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
static_cast<PropertyAttributes>(attribute));
}
......@@ -1144,20 +1119,6 @@ static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
}
static inline void AddPropertyToTemplate(
i::Handle<i::TemplateInfo> info,
i::Handle<i::AccessorInfo> obj) {
i::Isolate* isolate = info->GetIsolate();
i::Handle<i::Object> list(info->property_accessors(), isolate);
if (list->IsUndefined()) {
list = NeanderArray(isolate).value();
info->set_property_accessors(*list);
}
NeanderArray array(list);
array.add(isolate, obj);
}
static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
i::Isolate* isolate,
Template* template_obj) {
......@@ -1184,14 +1145,14 @@ static bool TemplateSetAccessor(
AccessControl settings,
PropertyAttribute attribute,
v8::Local<AccessorSignature> signature) {
i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
auto isolate = Utils::OpenHandle(template_obj)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
name, getter, setter, data, settings, attribute, signature);
auto obj = MakeAccessorInfo(name, getter, setter, data, settings, attribute,
signature);
if (obj.is_null()) return false;
i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
AddPropertyToTemplate(info, obj);
auto info = GetTemplateInfo(isolate, template_obj);
i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
return true;
}
......
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