Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: src/api-natives.cc

Issue 2099983004: Revert of Refactor CreateApiFunction (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/api-natives.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/api-natives.cc
diff --git a/src/api-natives.cc b/src/api-natives.cc
index fdf2c81d87f6f8b865e2db95a28848667fe42526..f09f42d5f0480f76b8d6ac4c0e54efb0f6a9314e 100644
--- a/src/api-natives.cc
+++ b/src/api-natives.cc
@@ -371,12 +371,43 @@
return handle(JSFunction::cast(element), isolate);
}
}
-
// Enter a new scope. Recursion could otherwise create a lot of handles.
HandleScope scope(isolate);
-
- auto function =
- ApiNatives::CreateApiFunction(isolate, data, JS_API_OBJECT_TYPE);
+ Handle<JSObject> prototype;
+ if (!data->remove_prototype()) {
+ auto prototype_templ = handle(data->prototype_template(), isolate);
+ if (prototype_templ->IsUndefined(isolate)) {
+ prototype = isolate->factory()->NewJSObject(isolate->object_function());
+ } else {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, prototype,
+ InstantiateObject(isolate,
+ Handle<ObjectTemplateInfo>::cast(prototype_templ),
+ Handle<JSReceiver>(), data->hidden_prototype()),
+ JSFunction);
+ }
+ auto parent = handle(data->parent_template(), isolate);
+ if (!parent->IsUndefined(isolate)) {
+ Handle<JSFunction> parent_instance;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, parent_instance,
+ InstantiateFunction(isolate,
+ Handle<FunctionTemplateInfo>::cast(parent)),
+ JSFunction);
+ // TODO(dcarney): decide what to do here.
+ Handle<Object> parent_prototype;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, parent_prototype,
+ JSObject::GetProperty(parent_instance,
+ isolate->factory()->prototype_string()),
+ JSFunction);
+ MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false,
+ Object::THROW_ON_ERROR),
+ MaybeHandle<JSFunction>());
+ }
+ }
+ auto function = ApiNatives::CreateApiFunction(
+ isolate, data, prototype, ApiNatives::JavaScriptObjectType);
if (!name.is_null() && name->IsString()) {
function->shared()->set_name(*name);
}
@@ -502,17 +533,20 @@
array.add(isolate, property);
}
+
Handle<JSFunction> ApiNatives::CreateApiFunction(
- Isolate* isolate, Handle<FunctionTemplateInfo> obj, InstanceType type) {
+ Isolate* isolate, Handle<FunctionTemplateInfo> obj,
+ Handle<Object> prototype, ApiInstanceType instance_type) {
Handle<SharedFunctionInfo> shared =
FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj);
- DCHECK(shared->IsApiFunction());
Handle<JSFunction> result =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared, isolate->native_context());
if (obj->remove_prototype()) {
result->set_map(*isolate->sloppy_function_without_prototype_map());
+ DCHECK(prototype.is_null());
+ DCHECK(result->shared()->IsApiFunction());
DCHECK(!result->has_initial_map());
DCHECK(!result->has_prototype());
DCHECK(!result->IsConstructor());
@@ -522,81 +556,78 @@
// Down from here is only valid for API functions that can be used as a
// constructor (don't set the "remove prototype" flag).
- // Set up function.prototype.
- Handle<JSObject> prototype;
- auto prototype_templ = handle(obj->prototype_template(), isolate);
- if (type != JS_API_OBJECT_TYPE || prototype_templ->IsUndefined(isolate)) {
+ if (obj->read_only_prototype()) {
+ result->set_map(*isolate->sloppy_function_with_readonly_prototype_map());
+ }
+
+ if (prototype->IsTheHole(isolate)) {
prototype = isolate->factory()->NewFunctionPrototype(result);
} else {
- prototype = internal::InstantiateObject(
- isolate, Handle<ObjectTemplateInfo>::cast(prototype_templ),
- Handle<JSReceiver>(), obj->hidden_prototype())
- .ToHandleChecked();
-
JSObject::AddProperty(Handle<JSObject>::cast(prototype),
isolate->factory()->constructor_string(), result,
DONT_ENUM);
}
- // Set up function.prototype.__proto__.
- auto parent = handle(obj->parent_template(), isolate);
- if (!parent->IsUndefined(isolate)) {
- Handle<JSFunction> parent_instance =
- internal::InstantiateFunction(
- isolate, Handle<FunctionTemplateInfo>::cast(parent))
- .ToHandleChecked();
- Handle<Object> parent_prototype =
- JSFunction::GetPrototype(isolate, parent_instance);
- CHECK(JSObject::SetPrototype(prototype, parent_prototype, false,
- Object::THROW_ON_ERROR)
- .IsJust());
- }
-
- if (obj->read_only_prototype()) {
- result->set_map(*isolate->sloppy_function_with_readonly_prototype_map());
- }
-
- // Set up the function's initial map.
+
int internal_field_count = 0;
if (!obj->instance_template()->IsUndefined(isolate)) {
- Handle<ObjectTemplateInfo> instance_template(
+ Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>(
ObjectTemplateInfo::cast(obj->instance_template()));
internal_field_count =
Smi::cast(instance_template->internal_field_count())->value();
}
+ // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing
+ // JSObject::GetHeaderSize.
int instance_size = kPointerSize * internal_field_count;
- switch (type) {
- case JS_API_OBJECT_TYPE:
- if (obj->needs_access_check() ||
- !obj->named_property_handler()->IsUndefined(isolate) ||
- !obj->indexed_property_handler()->IsUndefined(isolate)) {
+ InstanceType type;
+ switch (instance_type) {
+ case JavaScriptObjectType:
+ if (!obj->needs_access_check() &&
+ obj->named_property_handler()->IsUndefined(isolate) &&
+ obj->indexed_property_handler()->IsUndefined(isolate)) {
+ type = JS_API_OBJECT_TYPE;
+ } else {
type = JS_SPECIAL_API_OBJECT_TYPE;
}
instance_size += JSObject::kHeaderSize;
break;
- case JS_GLOBAL_OBJECT_TYPE:
+ case GlobalObjectType:
+ type = JS_GLOBAL_OBJECT_TYPE;
instance_size += JSGlobalObject::kSize;
break;
- case JS_GLOBAL_PROXY_TYPE:
+ case GlobalProxyType:
+ type = JS_GLOBAL_PROXY_TYPE;
instance_size += JSGlobalProxy::kSize;
break;
default:
UNREACHABLE();
+ type = JS_OBJECT_TYPE; // Keep the compiler happy.
break;
}
Handle<Map> map =
isolate->factory()->NewMap(type, instance_size, FAST_HOLEY_SMI_ELEMENTS);
- JSFunction::SetInitialMap(result, map, prototype);
-
- if (obj->undetectable()) map->set_is_undetectable();
- if (obj->needs_access_check()) map->set_is_access_check_needed(true);
+ JSFunction::SetInitialMap(result, map, Handle<JSObject>::cast(prototype));
+
+ // Mark as undetectable if needed.
+ if (obj->undetectable()) {
+ map->set_is_undetectable();
+ }
+
+ // Mark as needs_access_check if needed.
+ if (obj->needs_access_check()) {
+ map->set_is_access_check_needed(true);
+ }
+
+ // Set interceptor information in the map.
if (!obj->named_property_handler()->IsUndefined(isolate)) {
map->set_has_named_interceptor();
}
if (!obj->indexed_property_handler()->IsUndefined(isolate)) {
map->set_has_indexed_interceptor();
}
+
+ // Mark instance as callable in the map.
if (!obj->instance_call_handler()->IsUndefined(isolate)) {
map->set_is_callable();
map->set_is_constructor(true);
« no previous file with comments | « src/api-natives.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698