Index: src/api-natives.cc |
diff --git a/src/api-natives.cc b/src/api-natives.cc |
index 1bd71b00f96ef3c4b41482c8fefeebf758f9a7bd..f09f42d5f0480f76b8d6ac4c0e54efb0f6a9314e 100644 |
--- a/src/api-natives.cc |
+++ b/src/api-natives.cc |
@@ -537,95 +537,77 @@ void ApiNatives::AddNativeDataProperty(Isolate* isolate, |
Handle<JSFunction> ApiNatives::CreateApiFunction( |
Isolate* isolate, Handle<FunctionTemplateInfo> obj, |
Handle<Object> prototype, ApiInstanceType instance_type) { |
- Handle<Code> code; |
- if (obj->call_code()->IsCallHandlerInfo() && |
- CallHandlerInfo::cast(obj->call_code())->fast_handler()->IsCode()) { |
- code = isolate->builtins()->HandleFastApiCall(); |
- } else { |
- code = isolate->builtins()->HandleApiCall(); |
- } |
- Handle<Code> construct_stub = |
- prototype.is_null() ? isolate->builtins()->ConstructedNonConstructable() |
- : isolate->builtins()->JSConstructStubApi(); |
- |
- obj->set_instantiated(true); |
- Handle<JSFunction> result; |
- if (obj->remove_prototype()) { |
- result = isolate->factory()->NewFunctionWithoutPrototype( |
- isolate->factory()->empty_string(), code); |
- } else { |
- int internal_field_count = 0; |
- if (!obj->instance_template()->IsUndefined(isolate)) { |
- 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; |
- 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 GlobalObjectType: |
- type = JS_GLOBAL_OBJECT_TYPE; |
- instance_size += JSGlobalObject::kSize; |
- break; |
- case GlobalProxyType: |
- type = JS_GLOBAL_PROXY_TYPE; |
- instance_size += JSGlobalProxy::kSize; |
- break; |
- default: |
- UNREACHABLE(); |
- type = JS_OBJECT_TYPE; // Keep the compiler happy. |
- break; |
- } |
- |
- result = isolate->factory()->NewFunction( |
- isolate->factory()->empty_string(), code, prototype, type, |
- instance_size, obj->read_only_prototype(), true); |
- } |
- |
- result->shared()->set_length(obj->length()); |
- Handle<Object> class_name(obj->class_name(), isolate); |
- if (class_name->IsString()) { |
- result->shared()->set_instance_class_name(*class_name); |
- result->shared()->set_name(*class_name); |
- } |
- result->shared()->set_api_func_data(*obj); |
- result->shared()->set_construct_stub(*construct_stub); |
- result->shared()->DontAdaptArguments(); |
+ Handle<SharedFunctionInfo> shared = |
+ FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); |
+ 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()); |
return result; |
} |
-#ifdef DEBUG |
- LookupIterator it(handle(JSObject::cast(result->prototype())), |
- isolate->factory()->constructor_string(), |
- LookupIterator::OWN_SKIP_INTERCEPTOR); |
- MaybeHandle<Object> maybe_prop = Object::GetProperty(&it); |
- DCHECK(it.IsFound()); |
- DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result)); |
-#endif |
- |
// Down from here is only valid for API functions that can be used as a |
// constructor (don't set the "remove prototype" flag). |
- Handle<Map> map(result->initial_map()); |
+ 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 { |
+ JSObject::AddProperty(Handle<JSObject>::cast(prototype), |
+ isolate->factory()->constructor_string(), result, |
+ DONT_ENUM); |
+ } |
+ |
+ int internal_field_count = 0; |
+ if (!obj->instance_template()->IsUndefined(isolate)) { |
+ 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; |
+ 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 GlobalObjectType: |
+ type = JS_GLOBAL_OBJECT_TYPE; |
+ instance_size += JSGlobalObject::kSize; |
+ break; |
+ 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, Handle<JSObject>::cast(prototype)); |
// Mark as undetectable if needed. |
if (obj->undetectable()) { |
@@ -651,7 +633,6 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( |
map->set_is_constructor(true); |
} |
- DCHECK(result->shared()->IsApiFunction()); |
return result; |
} |