[runtime] Cleanup JSFunction creation in bootstrapper.

This is a preliminary step before we stop swapping maps in the bootstrapper
(strict/sloppy map with writable prototype <-> readonly prototype).

Bug: v8:6459
Change-Id: I120550c10e98a234e283d79a8d408096601c92af
Reviewed-on: https://chromium-review.googlesource.com/558879
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46403}
This commit is contained in:
Igor Sheludko 2017-07-03 15:40:13 +02:00 committed by Commit Bot
parent f447e678a6
commit b78511bd4e
5 changed files with 198 additions and 223 deletions

View File

@ -130,7 +130,9 @@ class Genesis BASE_EMBEDDED {
Handle<JSFunction> GetStrictArgumentsPoisonFunction(); Handle<JSFunction> GetStrictArgumentsPoisonFunction();
Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name); Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
void CreateSloppyModeFunctionMaps(Handle<JSFunction> empty);
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
void CreateObjectFunction(Handle<JSFunction> empty);
void CreateIteratorMaps(Handle<JSFunction> empty); void CreateIteratorMaps(Handle<JSFunction> empty);
void CreateAsyncIteratorMaps(Handle<JSFunction> empty); void CreateAsyncIteratorMaps(Handle<JSFunction> empty);
void CreateAsyncFunctionMaps(Handle<JSFunction> empty); void CreateAsyncFunctionMaps(Handle<JSFunction> empty);
@ -384,24 +386,25 @@ Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, Handle<String> name,
return fun; return fun;
} }
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base, Handle<JSFunction> SimpleInstallFunction(
Handle<Name> property_name, Handle<JSObject> base, Handle<Name> property_name,
Handle<String> function_name, Handle<String> function_name, Builtins::Name call, int len, bool adapt,
Builtins::Name call, int len, PropertyAttributes attrs = DONT_ENUM,
bool adapt, BuiltinFunctionId id = kInvalidBuiltinFunctionId) {
PropertyAttributes attrs = DONT_ENUM) {
Handle<JSFunction> fun = Handle<JSFunction> fun =
SimpleCreateFunction(base->GetIsolate(), function_name, call, len, adapt); SimpleCreateFunction(base->GetIsolate(), function_name, call, len, adapt);
if (id != kInvalidBuiltinFunctionId) {
fun->shared()->set_builtin_function_id(id);
}
InstallFunction(base, fun, property_name, attrs); InstallFunction(base, fun, property_name, attrs);
return fun; return fun;
} }
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base, Handle<JSFunction> SimpleInstallFunction(
Handle<String> name, Handle<JSObject> base, Handle<String> name, Builtins::Name call, int len,
Builtins::Name call, int len, bool adapt, PropertyAttributes attrs = DONT_ENUM,
bool adapt, BuiltinFunctionId id = kInvalidBuiltinFunctionId) {
PropertyAttributes attrs = DONT_ENUM) { return SimpleInstallFunction(base, name, name, call, len, adapt, attrs, id);
return SimpleInstallFunction(base, name, name, call, len, adapt, attrs);
} }
Handle<JSFunction> SimpleInstallFunction( Handle<JSFunction> SimpleInstallFunction(
@ -410,31 +413,25 @@ Handle<JSFunction> SimpleInstallFunction(
PropertyAttributes attrs = DONT_ENUM, PropertyAttributes attrs = DONT_ENUM,
BuiltinFunctionId id = kInvalidBuiltinFunctionId) { BuiltinFunctionId id = kInvalidBuiltinFunctionId) {
Factory* const factory = base->GetIsolate()->factory(); Factory* const factory = base->GetIsolate()->factory();
Handle<JSFunction> fun = SimpleInstallFunction( return SimpleInstallFunction(base, property_name,
base, property_name, factory->InternalizeUtf8String(function_name), call, factory->InternalizeUtf8String(function_name),
len, adapt, attrs); call, len, adapt, attrs, id);
if (id != kInvalidBuiltinFunctionId) {
fun->shared()->set_builtin_function_id(id);
}
return fun;
} }
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base, Handle<JSFunction> SimpleInstallFunction(
const char* name, Builtins::Name call, Handle<JSObject> base, const char* name, Builtins::Name call, int len,
int len, bool adapt, bool adapt, PropertyAttributes attrs = DONT_ENUM,
PropertyAttributes attrs = DONT_ENUM) { BuiltinFunctionId id = kInvalidBuiltinFunctionId) {
Factory* const factory = base->GetIsolate()->factory(); Factory* const factory = base->GetIsolate()->factory();
return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call, return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
len, adapt, attrs); len, adapt, attrs, id);
} }
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base, Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
const char* name, Builtins::Name call, const char* name, Builtins::Name call,
int len, bool adapt, int len, bool adapt,
BuiltinFunctionId id) { BuiltinFunctionId id) {
Handle<JSFunction> fun = SimpleInstallFunction(base, name, call, len, adapt); return SimpleInstallFunction(base, name, call, len, adapt, DONT_ENUM, id);
fun->shared()->set_builtin_function_id(id);
return fun;
} }
void SimpleInstallGetterSetter(Handle<JSObject> base, Handle<String> name, void SimpleInstallGetterSetter(Handle<JSObject> base, Handle<String> name,
@ -511,92 +508,20 @@ void InstallSpeciesGetter(Handle<JSFunction> constructor) {
} // namespace } // namespace
Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
// Allocate the map for function instances. Maps are allocated first and their
// prototypes patched later, once empty function is created.
// Functions with this map will not have a 'prototype' property, and
// can not be used as constructors.
Handle<Map> function_without_prototype_map =
factory()->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
native_context()->set_sloppy_function_without_prototype_map(
*function_without_prototype_map);
// Allocate the function map. This map is temporary, used only for processing
// of builtins.
// Later the map is replaced with writable prototype map, allocated below.
Handle<Map> function_map =
factory()->CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
native_context()->set_sloppy_function_map(*function_map);
native_context()->set_sloppy_function_with_readonly_prototype_map(
*function_map);
// The final map for functions. Writeable prototype.
// This map is installed in MakeFunctionInstancePrototypeWritable.
sloppy_function_map_writable_prototype_ =
factory()->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> object_name = factory->Object_string(); // Allocate the function map first and then patch the prototype later.
Handle<JSObject> object_function_prototype;
{ // --- O b j e c t ---
Handle<JSFunction> object_fun = factory->NewFunction(object_name);
int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
Handle<Map> object_function_map =
factory->NewMap(JS_OBJECT_TYPE, instance_size);
object_function_map->SetInObjectProperties(unused);
JSFunction::SetInitialMap(object_fun, object_function_map,
isolate->factory()->null_value());
object_function_map->set_unused_property_fields(unused);
native_context()->set_object_function(*object_fun);
// Allocate a new prototype for the object function.
object_function_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
"EmptyObjectPrototype");
map->set_is_prototype_map(true);
// Ban re-setting Object.prototype.__proto__ to prevent Proxy security bug
map->set_immutable_proto(true);
object_function_prototype->set_map(*map);
native_context()->set_initial_object_prototype(*object_function_prototype);
JSFunction::SetPrototype(object_fun, object_function_prototype);
JSObject::AddProperty(object_function_prototype,
factory->constructor_string(), object_fun, DONT_ENUM);
{
// Set up slow map for Object.create(null) instances without in-object
// properties.
Handle<Map> map(object_fun->initial_map(), isolate);
map = Map::CopyInitialMapNormalized(map);
Map::SetPrototype(map, isolate->factory()->null_value());
native_context()->set_slow_object_with_null_prototype_map(*map);
// Set up slow map for literals with too many properties.
map = Map::Copy(map, "slow_object_with_object_prototype_map");
Map::SetPrototype(map, object_function_prototype);
native_context()->set_slow_object_with_object_prototype_map(*map);
}
}
// Allocate the empty function as the prototype for function - ES6 19.2.3
Handle<Code> code(isolate->builtins()->EmptyFunction());
Handle<JSFunction> empty_function =
factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
// Allocate the function map first and then patch the prototype later
Handle<Map> empty_function_map = Handle<Map> empty_function_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE); factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
DCHECK(!empty_function_map->is_dictionary_map());
Map::SetPrototype(empty_function_map, object_function_prototype);
empty_function_map->set_is_prototype_map(true); empty_function_map->set_is_prototype_map(true);
DCHECK(!empty_function_map->is_dictionary_map());
empty_function->set_map(*empty_function_map); // Allocate the empty function as the prototype for function according to
// ES#sec-properties-of-the-function-prototype-object
Handle<Code> code(isolate->builtins()->EmptyFunction());
Handle<JSFunction> empty_function =
factory->NewFunction(empty_function_map, factory->empty_string(), code);
empty_function->shared()->set_language_mode(STRICT);
// --- E m p t y --- // --- E m p t y ---
Handle<String> source = factory->NewStringFromStaticChars("() {}"); Handle<String> source = factory->NewStringFromStaticChars("() {}");
@ -610,18 +535,36 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
empty_function->shared()->DontAdaptArguments(); empty_function->shared()->DontAdaptArguments();
SharedFunctionInfo::SetScript(handle(empty_function->shared()), script); SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
// Set prototypes for the function maps.
Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
isolate);
Handle<Map> sloppy_function_without_prototype_map(
native_context()->sloppy_function_without_prototype_map(), isolate);
Map::SetPrototype(sloppy_function_map, empty_function);
Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
return empty_function; return empty_function;
} }
void Genesis::CreateSloppyModeFunctionMaps(Handle<JSFunction> empty) {
Factory* factory = isolate_->factory();
// Functions with this map will not have a 'prototype' property, and
// can not be used as constructors.
Handle<Map> function_without_prototype_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
Map::SetPrototype(function_without_prototype_map, empty);
native_context()->set_sloppy_function_without_prototype_map(
*function_without_prototype_map);
// Allocate the function map. This map is temporary, used only for processing
// of builtins.
// Later the map is replaced with writable prototype map, allocated below.
Handle<Map> function_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
Map::SetPrototype(function_map, empty);
native_context()->set_sloppy_function_map(*function_map);
native_context()->set_sloppy_function_with_readonly_prototype_map(
*function_map);
// The final map for functions. Writeable prototype.
// This map is installed in MakeFunctionInstancePrototypeWritable.
sloppy_function_map_writable_prototype_ =
factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Map::SetPrototype(sloppy_function_map_writable_prototype_, empty);
}
// Creates the %ThrowTypeError% function. // Creates the %ThrowTypeError% function.
Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic( Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
@ -703,6 +646,61 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
AddRestrictedFunctionProperties(empty); AddRestrictedFunctionProperties(empty);
} }
void Genesis::CreateObjectFunction(Handle<JSFunction> empty_function) {
Factory* factory = isolate_->factory();
// --- O b j e c t ---
int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
Handle<JSFunction> object_fun =
CreateFunction(isolate_, factory->Object_string(), JS_OBJECT_TYPE,
instance_size, factory->null_value(), Builtins::kIllegal);
native_context()->set_object_function(*object_fun);
{
// Finish setting up Object function's initial map.
Map* initial_map = object_fun->initial_map();
initial_map->SetInObjectProperties(unused);
initial_map->set_unused_property_fields(unused);
initial_map->set_elements_kind(HOLEY_ELEMENTS);
}
// Allocate a new prototype for the object function.
Handle<JSObject> object_function_prototype =
factory->NewFunctionPrototype(object_fun);
Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
"EmptyObjectPrototype");
map->set_is_prototype_map(true);
// Ban re-setting Object.prototype.__proto__ to prevent Proxy security bug
map->set_immutable_proto(true);
object_function_prototype->set_map(*map);
// Complete setting up empty function.
{
Handle<Map> empty_function_map(empty_function->map(), isolate_);
Map::SetPrototype(empty_function_map, object_function_prototype);
}
native_context()->set_initial_object_prototype(*object_function_prototype);
JSFunction::SetPrototype(object_fun, object_function_prototype);
{
// Set up slow map for Object.create(null) instances without in-object
// properties.
Handle<Map> map(object_fun->initial_map(), isolate_);
map = Map::CopyInitialMapNormalized(map);
Map::SetPrototype(map, factory->null_value());
native_context()->set_slow_object_with_null_prototype_map(*map);
// Set up slow map for literals with too many properties.
map = Map::Copy(map, "slow_object_with_object_prototype_map");
Map::SetPrototype(map, object_function_prototype);
native_context()->set_slow_object_with_object_prototype_map(*map);
}
}
void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) { void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
// Create iterator-related meta-objects. // Create iterator-related meta-objects.
Handle<JSObject> iterator_prototype = Handle<JSObject> iterator_prototype =
@ -902,14 +900,9 @@ void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) {
} }
void Genesis::CreateJSProxyMaps() { void Genesis::CreateJSProxyMaps() {
// Allocate the different maps for all Proxy types. // Allocate maps for all Proxy types.
// Next to the default proxy, we need maps indicating callable and // Next to the default proxy, we need maps indicating callable and
// constructable proxies. // constructable proxies.
Handle<Map> proxy_function_map =
Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
proxy_function_map->set_is_constructor(true);
native_context()->set_proxy_function_map(*proxy_function_map);
Handle<Map> proxy_map = Handle<Map> proxy_map =
factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, PACKED_ELEMENTS); factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, PACKED_ELEMENTS);
proxy_map->set_dictionary_map(true); proxy_map->set_dictionary_map(true);
@ -1044,8 +1037,9 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals(
Handle<Code> code = isolate()->builtins()->Illegal(); Handle<Code> code = isolate()->builtins()->Illegal();
Handle<JSObject> prototype = Handle<JSObject> prototype =
factory()->NewFunctionPrototype(isolate()->object_function()); factory()->NewFunctionPrototype(isolate()->object_function());
js_global_object_function = factory()->NewFunction( js_global_object_function =
name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize); factory()->NewFunction(name, code, prototype, JS_GLOBAL_OBJECT_TYPE,
JSGlobalObject::kSize, STRICT);
#ifdef DEBUG #ifdef DEBUG
LookupIterator it(prototype, factory()->constructor_string(), LookupIterator it(prototype, factory()->constructor_string(),
LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
@ -1371,20 +1365,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Builtins::kFunctionPrototypeToString, 0, false); Builtins::kFunctionPrototypeToString, 0, false);
// Install the @@hasInstance function. // Install the @@hasInstance function.
Handle<JSFunction> has_instance = InstallFunction( Handle<JSFunction> has_instance = SimpleInstallFunction(
prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE, prototype, factory->has_instance_symbol(), "[Symbol.hasInstance]",
JSObject::kHeaderSize, MaybeHandle<JSObject>(), Builtins::kFunctionPrototypeHasInstance, 1, true,
Builtins::kFunctionPrototypeHasInstance, static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY),
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); kFunctionHasInstance);
has_instance->shared()->set_builtin_function_id(kFunctionHasInstance);
native_context()->set_function_has_instance(*has_instance); native_context()->set_function_has_instance(*has_instance);
// Set the expected parameters for @@hasInstance to 1; required by builtin.
has_instance->shared()->set_internal_formal_parameter_count(1);
// Set the length for the function to satisfy ECMA-262.
has_instance->shared()->set_length(1);
// Install the "constructor" property on the %FunctionPrototype%. // Install the "constructor" property on the %FunctionPrototype%.
JSObject::AddProperty(prototype, factory->constructor_string(), JSObject::AddProperty(prototype, factory->constructor_string(),
function_fun, DONT_ENUM); function_fun, DONT_ENUM);
@ -1526,17 +1513,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
factory->ArrayIterator_string(), factory->ArrayIterator_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> next = InstallFunction( SimpleInstallFunction(array_iterator_prototype, "next",
array_iterator_prototype, "next", JS_OBJECT_TYPE, JSObject::kHeaderSize, Builtins::kArrayIteratorPrototypeNext, 0, true,
MaybeHandle<JSObject>(), Builtins::kArrayIteratorPrototypeNext); kArrayIteratorNext);
next->shared()->set_builtin_function_id(kArrayIteratorNext);
// Set the expected parameters for %ArrayIteratorPrototype%.next to 0 (not
// including the receiver), as required by the builtin.
next->shared()->set_internal_formal_parameter_count(0);
// Set the length for the function to satisfy ECMA-262.
next->shared()->set_length(0);
Handle<JSFunction> array_iterator_function = CreateFunction( Handle<JSFunction> array_iterator_function = CreateFunction(
isolate, factory->ArrayIterator_string(), isolate, factory->ArrayIterator_string(),
@ -1867,12 +1846,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(prototype, "valueOf", SimpleInstallFunction(prototype, "valueOf",
Builtins::kStringPrototypeValueOf, 0, true); Builtins::kStringPrototypeValueOf, 0, true);
Handle<JSFunction> iterator = SimpleCreateFunction( SimpleInstallFunction(prototype, factory->iterator_symbol(),
isolate, factory->NewStringFromAsciiChecked("[Symbol.iterator]"), "[Symbol.iterator]",
Builtins::kStringPrototypeIterator, 0, true); Builtins::kStringPrototypeIterator, 0, true,
iterator->shared()->set_builtin_function_id(kStringIterator); DONT_ENUM, kStringIterator);
JSObject::AddProperty(prototype, factory->iterator_symbol(), iterator,
static_cast<PropertyAttributes>(DONT_ENUM));
} }
{ // --- S t r i n g I t e r a t o r --- { // --- S t r i n g I t e r a t o r ---
@ -1888,18 +1865,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
factory->NewStringFromAsciiChecked("String Iterator"), factory->NewStringFromAsciiChecked("String Iterator"),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> next = SimpleInstallFunction(string_iterator_prototype, "next",
InstallFunction(string_iterator_prototype, "next", JS_OBJECT_TYPE, Builtins::kStringIteratorPrototypeNext, 0, true,
JSObject::kHeaderSize, MaybeHandle<JSObject>(), kStringIteratorNext);
Builtins::kStringIteratorPrototypeNext);
next->shared()->set_builtin_function_id(kStringIteratorNext);
// Set the expected parameters for %StringIteratorPrototype%.next to 0 (not
// including the receiver), as required by the builtin.
next->shared()->set_internal_formal_parameter_count(0);
// Set the length for the function to satisfy ECMA-262.
next->shared()->set_length(0);
Handle<JSFunction> string_iterator_function = CreateFunction( Handle<JSFunction> string_iterator_function = CreateFunction(
isolate, factory->NewStringFromAsciiChecked("StringIterator"), isolate, factory->NewStringFromAsciiChecked("StringIterator"),
@ -2426,12 +2394,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // Internal: RegExpInternalMatch { // Internal: RegExpInternalMatch
Handle<JSFunction> function = Handle<JSFunction> function =
factory->NewFunction(isolate->factory()->empty_string(), SimpleCreateFunction(isolate, isolate->factory()->empty_string(),
isolate->builtins()->RegExpInternalMatch(), Builtins::kRegExpInternalMatch, 2, true);
JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->shared()->set_internal_formal_parameter_count(2);
function->shared()->set_length(2);
function->shared()->set_native(true);
native_context()->set(Context::REGEXP_INTERNAL_MATCH, *function); native_context()->set(Context::REGEXP_INTERNAL_MATCH, *function);
} }
@ -2598,7 +2562,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // -- C o n s o l e { // -- C o n s o l e
Handle<String> name = factory->InternalizeUtf8String("console"); Handle<String> name = factory->InternalizeUtf8String("console");
Handle<JSFunction> cons = factory->NewFunction(name); Handle<JSFunction> cons = factory->NewFunction(
isolate->strict_function_map(), name, MaybeHandle<Code>());
Handle<JSObject> empty = factory->NewJSObject(isolate->object_function()); Handle<JSObject> empty = factory->NewJSObject(isolate->object_function());
JSFunction::SetPrototype(cons, empty); JSFunction::SetPrototype(cons, empty);
Handle<JSObject> console = factory->NewJSObject(cons, TENURED); Handle<JSObject> console = factory->NewJSObject(cons, TENURED);
@ -3124,16 +3089,17 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // -- P r o x y { // -- P r o x y
CreateJSProxyMaps(); CreateJSProxyMaps();
Handle<Map> proxy_function_map =
Map::Copy(isolate->sloppy_function_without_prototype_map(), "Proxy");
proxy_function_map->set_is_constructor(true);
Handle<String> name = factory->Proxy_string(); Handle<String> name = factory->Proxy_string();
Handle<Code> code(isolate->builtins()->ProxyConstructor()); Handle<Code> code(isolate->builtins()->ProxyConstructor());
Handle<JSFunction> proxy_function = Handle<JSFunction> proxy_function =
factory->NewFunction(isolate->proxy_function_map(), factory->NewFunction(proxy_function_map, name, code);
factory->Proxy_string(), MaybeHandle<Code>(code));
JSFunction::SetInitialMap( JSFunction::SetInitialMap(proxy_function, isolate->proxy_map(),
proxy_function, Handle<Map>(native_context()->proxy_map(), isolate), factory->null_value());
factory->null_value());
proxy_function->shared()->SetConstructStub( proxy_function->shared()->SetConstructStub(
*isolate->builtins()->ProxyConstructor_ConstructStub()); *isolate->builtins()->ProxyConstructor_ConstructStub());
@ -3227,8 +3193,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
// class_name equals 'Arguments'. // class_name equals 'Arguments'.
Handle<String> arguments_string = factory->Arguments_string(); Handle<String> arguments_string = factory->Arguments_string();
Handle<Code> code = isolate->builtins()->Illegal(); Handle<Code> code = isolate->builtins()->Illegal();
Handle<JSFunction> function = factory->NewFunctionWithoutPrototype( Handle<JSFunction> function =
arguments_string, code); factory->NewFunctionWithoutPrototype(arguments_string, code, STRICT);
function->shared()->set_instance_class_name(*arguments_string); function->shared()->set_instance_class_name(*arguments_string);
Handle<Map> map = factory->NewMap( Handle<Map> map = factory->NewMap(
@ -3323,34 +3289,28 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // --- context extension { // --- context extension
// Create a function for the context extension objects. // Create a function for the context extension objects.
Handle<Code> code = isolate->builtins()->Illegal(); Handle<JSFunction> context_extension_fun = CreateFunction(
Handle<JSFunction> context_extension_fun = factory->NewFunction( isolate, factory->empty_string(), JS_CONTEXT_EXTENSION_OBJECT_TYPE,
factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE, JSObject::kHeaderSize, factory->the_hole_value(), Builtins::kIllegal);
JSObject::kHeaderSize); Handle<String> name = factory->InternalizeUtf8String("context_extension");
Handle<String> name = factory->InternalizeOneByteString(
STATIC_CHAR_VECTOR("context_extension"));
context_extension_fun->shared()->set_instance_class_name(*name); context_extension_fun->shared()->set_instance_class_name(*name);
native_context()->set_context_extension_function(*context_extension_fun); native_context()->set_context_extension_function(*context_extension_fun);
} }
{ {
// Set up the call-as-function delegate. // Set up the call-as-function delegate.
Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction(); Handle<JSFunction> delegate =
Handle<JSFunction> delegate = factory->NewFunction( SimpleCreateFunction(isolate, factory->empty_string(),
factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize); Builtins::kHandleApiCallAsFunction, 0, false);
native_context()->set_call_as_function_delegate(*delegate); native_context()->set_call_as_function_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
} }
{ {
// Set up the call-as-constructor delegate. // Set up the call-as-constructor delegate.
Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor(); Handle<JSFunction> delegate =
Handle<JSFunction> delegate = factory->NewFunction( SimpleCreateFunction(isolate, factory->empty_string(),
factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize); Builtins::kHandleApiCallAsConstructor, 0, false);
native_context()->set_call_as_constructor_delegate(*delegate); native_context()->set_call_as_constructor_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
} }
} // NOLINT(readability/fn_size) } // NOLINT(readability/fn_size)
@ -4291,12 +4251,11 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
// Builtin function for OpaqueReference -- a JSValue-based object, // Builtin function for OpaqueReference -- a JSValue-based object,
// that keeps its field isolated from JavaScript code. It may store // that keeps its field isolated from JavaScript code. It may store
// objects, that JavaScript code may not access. // objects, that JavaScript code may not access.
Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
factory()->empty_string(), isolate()->builtins()->Illegal(),
isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
Handle<JSObject> prototype = Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED); factory()->NewJSObject(isolate()->object_function(), TENURED);
JSFunction::SetPrototype(opaque_reference_fun, prototype); Handle<JSFunction> opaque_reference_fun =
CreateFunction(isolate(), factory()->empty_string(), JS_VALUE_TYPE,
JSValue::kSize, prototype, Builtins::kIllegal);
native_context()->set_opaque_reference_function(*opaque_reference_fun); native_context()->set_opaque_reference_function(*opaque_reference_fun);
} }
@ -5161,7 +5120,9 @@ Genesis::Genesis(
// We get here if there was no context snapshot. // We get here if there was no context snapshot.
CreateRoots(); CreateRoots();
Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
CreateSloppyModeFunctionMaps(empty_function);
CreateStrictModeFunctionMaps(empty_function); CreateStrictModeFunctionMaps(empty_function);
CreateObjectFunction(empty_function);
CreateIteratorMaps(empty_function); CreateIteratorMaps(empty_function);
CreateAsyncIteratorMaps(empty_function); CreateAsyncIteratorMaps(empty_function);
CreateAsyncFunctionMaps(empty_function); CreateAsyncFunctionMaps(empty_function);

View File

@ -303,7 +303,6 @@ enum ContextLookupFlags {
V(PROXY_CALLABLE_MAP_INDEX, Map, proxy_callable_map) \ V(PROXY_CALLABLE_MAP_INDEX, Map, proxy_callable_map) \
V(PROXY_CONSTRUCTOR_MAP_INDEX, Map, proxy_constructor_map) \ V(PROXY_CONSTRUCTOR_MAP_INDEX, Map, proxy_constructor_map) \
V(PROXY_FUNCTION_INDEX, JSFunction, proxy_function) \ V(PROXY_FUNCTION_INDEX, JSFunction, proxy_function) \
V(PROXY_FUNCTION_MAP_INDEX, Map, proxy_function_map) \
V(PROXY_MAP_INDEX, Map, proxy_map) \ V(PROXY_MAP_INDEX, Map, proxy_map) \
V(PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN, SharedFunctionInfo, \ V(PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN, SharedFunctionInfo, \
promise_get_capabilities_executor_shared_fun) \ promise_get_capabilities_executor_shared_fun) \
@ -354,6 +353,8 @@ enum ContextLookupFlags {
V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \ V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \ V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
strict_function_without_prototype_map) \ strict_function_without_prototype_map) \
V(STRICT_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
strict_function_with_readonly_prototype_map) \
V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \ V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \
V(ASYNC_GENERATOR_FUNCTION_MAP_INDEX, Map, async_generator_function_map) \ V(ASYNC_GENERATOR_FUNCTION_MAP_INDEX, Map, async_generator_function_map) \
V(CLASS_FUNCTION_MAP_INDEX, Map, class_function_map) \ V(CLASS_FUNCTION_MAP_INDEX, Map, class_function_map) \

View File

@ -1456,27 +1456,41 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
return function; return function;
} }
Handle<JSFunction> Factory::NewFunction(Handle<Map> map, Handle<String> name,
Handle<JSFunction> Factory::NewFunction(Handle<Map> map, MaybeHandle<Code> maybe_code) {
Handle<String> name,
MaybeHandle<Code> code) {
Handle<Context> context(isolate()->native_context()); Handle<Context> context(isolate()->native_context());
Handle<SharedFunctionInfo> info = Handle<SharedFunctionInfo> info =
NewSharedFunctionInfo(name, code, map->is_constructor()); NewSharedFunctionInfo(name, maybe_code, map->is_constructor());
// Proper language mode in shared function info will be set outside. // Proper language mode in shared function info will be set outside.
DCHECK(is_sloppy(info->language_mode())); DCHECK(is_sloppy(info->language_mode()));
DCHECK(!map->IsUndefined(isolate())); DCHECK(!map->IsUndefined(isolate()));
DCHECK( #ifdef DEBUG
map.is_identical_to(isolate()->sloppy_function_map()) || if (isolate()->bootstrapper()->IsActive()) {
map.is_identical_to(isolate()->sloppy_function_without_prototype_map()) || Handle<Code> code;
map.is_identical_to( bool has_code = maybe_code.ToHandle(&code);
isolate()->sloppy_function_with_readonly_prototype_map()) || DCHECK(
map.is_identical_to(isolate()->strict_function_map()) || // During bootstrapping some of these maps could be not created yet.
map.is_identical_to(isolate()->strict_function_without_prototype_map()) || (*map == context->get(Context::STRICT_FUNCTION_MAP_INDEX)) ||
// TODO(titzer): wasm_function_map() could be undefined here. ugly. (*map ==
(*map == context->get(Context::WASM_FUNCTION_MAP_INDEX)) || context->get(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)) ||
(*map == context->get(Context::NATIVE_FUNCTION_MAP_INDEX)) || (*map ==
map.is_identical_to(isolate()->proxy_function_map())); context->get(
Context::STRICT_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX)) ||
// Check if it's a creation of an empty or Proxy function during
// bootstrapping.
(has_code && (code->builtin_index() == Builtins::kEmptyFunction ||
code->builtin_index() == Builtins::kProxyConstructor)));
} else {
DCHECK(
(*map == *isolate()->sloppy_function_map()) ||
(*map == *isolate()->sloppy_function_without_prototype_map()) ||
(*map == *isolate()->sloppy_function_with_readonly_prototype_map()) ||
(*map == *isolate()->strict_function_map()) ||
(*map == *isolate()->strict_function_without_prototype_map()) ||
(*map == *isolate()->wasm_function_map()) ||
(*map == *isolate()->native_function_map()));
}
#endif
return NewFunction(map, info, context); return NewFunction(map, info, context);
} }
@ -1528,10 +1542,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
prototype = NewFunctionPrototype(function); prototype = NewFunctionPrototype(function);
} }
} }
JSFunction::SetInitialMap(function, initial_map, prototype);
JSFunction::SetInitialMap(function, initial_map,
Handle<JSReceiver>::cast(prototype));
return function; return function;
} }
@ -1540,7 +1551,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name,
Handle<Code> code, Handle<Code> code,
InstanceType type, InstanceType type,
int instance_size) { int instance_size) {
return NewFunction(name, code, the_hole_value(), type, instance_size); DCHECK(isolate()->bootstrapper()->IsActive());
return NewFunction(name, code, the_hole_value(), type, instance_size, STRICT);
} }

View File

@ -913,7 +913,8 @@ void WasmJs::Install(Isolate* isolate) {
// Setup WebAssembly // Setup WebAssembly
Handle<String> name = v8_str(isolate, "WebAssembly"); Handle<String> name = v8_str(isolate, "WebAssembly");
Handle<JSFunction> cons = factory->NewFunction(name); Handle<JSFunction> cons = factory->NewFunction(isolate->strict_function_map(),
name, MaybeHandle<Code>());
JSFunction::SetPrototype(cons, isolate->initial_object_prototype()); JSFunction::SetPrototype(cons, isolate->initial_object_prototype());
cons->shared()->set_instance_class_name(*name); cons->shared()->set_instance_class_name(*name);
Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED);