Commit d4395c52 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[factory] Remove NewFunctionArgs

They've been replaced by JSFunctionBuilder.

Bug: v8:8888
Change-Id: Ie37e37befaf313fd58da3ecb02ab7c040e696f8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2529134
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71102}
parent 074621e9
......@@ -10133,19 +10133,20 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScope handle_scope(isolate);
i::Builtins::Name builtin_id;
switch (builtin) {
case kStringToLowerCase:
builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
break;
default:
UNREACHABLE();
}
CHECK_EQ(builtin, kStringToLowerCase);
i::Builtins::Name builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
i::Factory* factory = isolate->factory();
i::Handle<i::String> name = isolate->factory()->empty_string();
i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
name, builtin_id, i::LanguageMode::kStrict);
i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
i::Handle<i::NativeContext> context(isolate->native_context());
i::Handle<i::SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name, builtin_id);
info->set_language_mode(i::LanguageMode::kStrict);
i::Handle<i::JSFunction> fun =
i::Factory::JSFunctionBuilder{isolate, info, context}
.set_map(isolate->strict_function_without_prototype_map())
.Build();
fun->shared().set_internal_formal_parameter_count(0);
fun->shared().set_length(0);
......
......@@ -123,17 +123,24 @@ BUILTIN(ConsoleTimeStamp) {
}
namespace {
void InstallContextFunction(Isolate* isolate, Handle<JSObject> target,
const char* name, Builtins::Name builtin_id,
int context_id, Handle<Object> context_name) {
Factory* const factory = isolate->factory();
Handle<NativeContext> context(isolate->native_context());
Handle<Map> map = isolate->sloppy_function_without_prototype_map();
Handle<String> name_string =
Name::ToFunctionName(isolate, factory->InternalizeUtf8String(name))
.ToHandleChecked();
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype(
name_string, builtin_id, i::LanguageMode::kSloppy);
Handle<JSFunction> fun = factory->NewFunction(args);
Handle<SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name_string, builtin_id);
info->set_language_mode(LanguageMode::kSloppy);
Handle<JSFunction> fun =
Factory::JSFunctionBuilder{isolate, info, context}.set_map(map).Build();
fun->shared().set_native(true);
fun->shared().DontAdaptArguments();
......@@ -147,6 +154,7 @@ void InstallContextFunction(Isolate* isolate, Handle<JSObject> target,
}
JSObject::AddProperty(isolate, target, name_string, fun, NONE);
}
} // namespace
BUILTIN(ConsoleContext) {
......@@ -154,9 +162,14 @@ BUILTIN(ConsoleContext) {
Factory* const factory = isolate->factory();
Handle<String> name = factory->InternalizeUtf8String("Context");
NewFunctionArgs arguments = NewFunctionArgs::ForFunctionWithoutCode(
name, isolate->sloppy_function_map(), LanguageMode::kSloppy);
Handle<JSFunction> cons = factory->NewFunction(arguments);
Handle<SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name, Builtins::kIllegal);
info->set_language_mode(LanguageMode::kSloppy);
Handle<JSFunction> cons =
Factory::JSFunctionBuilder{isolate, info, isolate->native_context()}
.set_map(isolate->sloppy_function_map())
.Build();
Handle<JSObject> prototype = factory->NewJSObject(isolate->object_function());
JSFunction::SetPrototype(cons, prototype);
......
......@@ -2701,6 +2701,17 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForApiFunction(
return shared;
}
Handle<SharedFunctionInfo>
Factory::NewSharedFunctionInfoForWasmExportedFunction(
Handle<String> name, Handle<WasmExportedFunctionData> data) {
return NewSharedFunctionInfo(name, data, Builtins::kNoBuiltinId);
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWasmJSFunction(
Handle<String> name, Handle<WasmJSFunctionData> data) {
return NewSharedFunctionInfo(name, data, Builtins::kNoBuiltinId);
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWasmCapiFunction(
Handle<WasmCapiFunctionData> data) {
return NewSharedFunctionInfo(MaybeHandle<String>(), data,
......@@ -3445,242 +3456,13 @@ bool Factory::EmptyStringRootIsInitialized() {
return isolate()->roots_table()[RootIndex::kempty_string] != kNullAddress;
}
// static
NewFunctionArgs NewFunctionArgs::ForWasm(
Handle<String> name,
Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map) {
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.maybe_map_ = map;
args.maybe_wasm_function_data_ = exported_function_data;
args.language_mode_ = LanguageMode::kSloppy;
args.prototype_mutability_ = MUTABLE;
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForWasm(
Handle<String> name, Handle<WasmJSFunctionData> js_function_data,
Handle<Map> map) {
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.maybe_map_ = map;
args.maybe_wasm_function_data_ = js_function_data;
args.language_mode_ = LanguageMode::kSloppy;
args.prototype_mutability_ = MUTABLE;
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForBuiltin(Handle<String> name,
Handle<Map> map, int builtin_id) {
DCHECK(Builtins::IsBuiltinId(builtin_id));
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.maybe_map_ = map;
args.maybe_builtin_id_ = builtin_id;
args.language_mode_ = LanguageMode::kStrict;
args.prototype_mutability_ = MUTABLE;
args.SetShouldSetLanguageMode();
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForFunctionWithoutCode(
Handle<String> name, Handle<Map> map, LanguageMode language_mode) {
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.maybe_map_ = map;
args.maybe_builtin_id_ = Builtins::kIllegal;
args.language_mode_ = language_mode;
args.prototype_mutability_ = MUTABLE;
args.SetShouldSetLanguageMode();
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForBuiltinWithPrototype(
Handle<String> name, Handle<HeapObject> prototype, InstanceType type,
int instance_size, int inobject_properties, int builtin_id,
MutableMode prototype_mutability) {
DCHECK(Builtins::IsBuiltinId(builtin_id));
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.type_ = type;
args.instance_size_ = instance_size;
args.inobject_properties_ = inobject_properties;
args.maybe_prototype_ = prototype;
args.maybe_builtin_id_ = builtin_id;
args.language_mode_ = LanguageMode::kStrict;
args.prototype_mutability_ = prototype_mutability;
args.SetShouldCreateAndSetInitialMap();
args.SetShouldSetPrototype();
args.SetShouldSetLanguageMode();
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForBuiltinWithoutPrototype(
Handle<String> name, int builtin_id, LanguageMode language_mode) {
DCHECK(Builtins::IsBuiltinId(builtin_id));
DCHECK(name->IsFlat());
NewFunctionArgs args;
args.name_ = name;
args.maybe_builtin_id_ = builtin_id;
args.language_mode_ = language_mode;
args.prototype_mutability_ = MUTABLE;
args.SetShouldSetLanguageMode();
return args;
}
void NewFunctionArgs::SetShouldCreateAndSetInitialMap() {
// Needed to create the initial map.
maybe_prototype_.Assert();
DCHECK_NE(kUninitialized, instance_size_);
DCHECK_NE(kUninitialized, inobject_properties_);
should_create_and_set_initial_map_ = true;
}
void NewFunctionArgs::SetShouldSetPrototype() {
maybe_prototype_.Assert();
should_set_prototype_ = true;
}
void NewFunctionArgs::SetShouldSetLanguageMode() {
DCHECK(language_mode_ == LanguageMode::kStrict ||
language_mode_ == LanguageMode::kSloppy);
should_set_language_mode_ = true;
}
Handle<Map> NewFunctionArgs::GetMap(Isolate* isolate) const {
if (!maybe_map_.is_null()) {
return maybe_map_.ToHandleChecked();
} else if (maybe_prototype_.is_null()) {
return is_strict(language_mode_)
? isolate->strict_function_without_prototype_map()
: isolate->sloppy_function_without_prototype_map();
} else {
DCHECK(!maybe_prototype_.is_null());
switch (prototype_mutability_) {
case MUTABLE:
return is_strict(language_mode_) ? isolate->strict_function_map()
: isolate->sloppy_function_map();
case IMMUTABLE:
return is_strict(language_mode_)
? isolate->strict_function_with_readonly_prototype_map()
: isolate->sloppy_function_with_readonly_prototype_map();
}
}
UNREACHABLE();
}
Handle<JSFunction> Factory::NewFunctionForTesting(Handle<String> name) {
NewFunctionArgs args = NewFunctionArgs::ForFunctionWithoutCode(
name, isolate()->sloppy_function_map(), LanguageMode::kSloppy);
Handle<JSFunction> result = NewFunction(args);
DCHECK(is_sloppy(result->shared().language_mode()));
return result;
}
Handle<JSFunction> Factory::NewFunction(const NewFunctionArgs& args) {
DCHECK(!args.name_.is_null());
// Create the SharedFunctionInfo.
Handle<NativeContext> context(isolate()->native_context());
Handle<Map> map = args.GetMap(isolate());
Handle<SharedFunctionInfo> info =
NewSharedFunctionInfo(args.name_, args.maybe_wasm_function_data_,
args.maybe_builtin_id_, kNormalFunction);
// Proper language mode in shared function info will be set later.
DCHECK(is_sloppy(info->language_mode()));
DCHECK(!map->IsUndefined(isolate()));
if (args.should_set_language_mode_) {
info->set_language_mode(args.language_mode_);
}
#ifdef DEBUG
if (isolate()->bootstrapper()->IsActive()) {
Handle<Code> code;
DCHECK(
// During bootstrapping some of these maps could be not created yet.
(*map == context->get(Context::STRICT_FUNCTION_MAP_INDEX)) ||
(*map ==
context->get(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)) ||
(*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.
(args.maybe_builtin_id_ == Builtins::kEmptyFunction ||
args.maybe_builtin_id_ == Builtins::kProxyConstructor));
}
#endif
Handle<JSFunction> result =
JSFunctionBuilder{isolate(), info, context}.set_map(map).Build();
// Both of these write to `prototype_or_initial_map`.
// TODO(jgruber): Fix callsites and enable the DCHECK.
// DCHECK(!args.should_set_prototype_ ||
// !args.should_create_and_set_initial_map_);
if (args.should_set_prototype_) {
result->set_prototype_or_initial_map(
*args.maybe_prototype_.ToHandleChecked());
}
if (args.should_create_and_set_initial_map_) {
ElementsKind elements_kind;
switch (args.type_) {
case JS_ARRAY_TYPE:
elements_kind = PACKED_SMI_ELEMENTS;
break;
case JS_ARGUMENTS_OBJECT_TYPE:
elements_kind = PACKED_ELEMENTS;
break;
default:
elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
break;
}
Handle<Map> initial_map = NewMap(args.type_, args.instance_size_,
elements_kind, args.inobject_properties_);
result->shared().set_expected_nof_properties(args.inobject_properties_);
// TODO(littledan): Why do we have this is_generator test when
// NewFunctionPrototype already handles finding an appropriately
// shared prototype?
Handle<HeapObject> prototype = args.maybe_prototype_.ToHandleChecked();
if (!IsResumableFunction(result->shared().kind())) {
if (prototype->IsTheHole(isolate())) {
prototype = NewFunctionPrototype(result);
}
}
JSFunction::SetInitialMap(result, initial_map, prototype);
}
return result;
NewSharedFunctionInfoForBuiltin(name, Builtins::kIllegal);
info->set_language_mode(LanguageMode::kSloppy);
return JSFunctionBuilder{isolate(), info, isolate()->native_context()}
.set_map(isolate()->sloppy_function_map())
.Build();
}
Factory::JSFunctionBuilder::JSFunctionBuilder(Isolate* isolate,
......
......@@ -56,7 +56,6 @@ class JSTypedArray;
class JSWeakMap;
class LoadHandler;
class NativeContext;
class NewFunctionArgs;
class PromiseResolveThenableJobTask;
class RegExpMatchInfo;
class ScriptContextTable;
......@@ -622,10 +621,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy(int size);
// Creates a new JSFunction according to the given args. This is the function
// you'll probably want to use when creating a JSFunction from the runtime.
Handle<JSFunction> NewFunction(const NewFunctionArgs& args);
// For testing only. Creates a sloppy function without code.
Handle<JSFunction> NewFunctionForTesting(Handle<String> name);
......@@ -698,6 +693,10 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
MaybeHandle<String> maybe_name,
Handle<FunctionTemplateInfo> function_template_info, FunctionKind kind);
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWasmExportedFunction(
Handle<String> name, Handle<WasmExportedFunctionData> data);
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWasmJSFunction(
Handle<String> name, Handle<WasmJSFunctionData> data);
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWasmCapiFunction(
Handle<WasmCapiFunctionData> data);
......@@ -1012,63 +1011,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
int capacity, AllocationType allocation = AllocationType::kYoung);
};
// Utility class to simplify argument handling around JSFunction creation.
class NewFunctionArgs final {
public:
static NewFunctionArgs ForWasm(
Handle<String> name,
Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map);
static NewFunctionArgs ForWasm(Handle<String> name,
Handle<WasmJSFunctionData> js_function_data,
Handle<Map> map);
V8_EXPORT_PRIVATE static NewFunctionArgs ForBuiltin(Handle<String> name,
Handle<Map> map,
int builtin_id);
static NewFunctionArgs ForFunctionWithoutCode(Handle<String> name,
Handle<Map> map,
LanguageMode language_mode);
static NewFunctionArgs ForBuiltinWithPrototype(
Handle<String> name, Handle<HeapObject> prototype, InstanceType type,
int instance_size, int inobject_properties, int builtin_id,
MutableMode prototype_mutability);
static NewFunctionArgs ForBuiltinWithoutPrototype(Handle<String> name,
int builtin_id,
LanguageMode language_mode);
Handle<Map> GetMap(Isolate* isolate) const;
private:
NewFunctionArgs() = default; // Use the static factory constructors.
void SetShouldCreateAndSetInitialMap();
void SetShouldSetPrototype();
void SetShouldSetLanguageMode();
// Sentinel value.
static const int kUninitialized = -1;
Handle<String> name_;
MaybeHandle<Map> maybe_map_;
MaybeHandle<Struct> maybe_wasm_function_data_;
bool should_create_and_set_initial_map_ = false;
InstanceType type_;
int instance_size_ = kUninitialized;
int inobject_properties_ = kUninitialized;
bool should_set_prototype_ = false;
MaybeHandle<HeapObject> maybe_prototype_;
bool should_set_language_mode_ = false;
LanguageMode language_mode_;
int maybe_builtin_id_ = kUninitialized;
MutableMode prototype_mutability_;
friend class Factory;
};
} // namespace internal
} // namespace v8
......
This diff is collapsed.
......@@ -2094,9 +2094,14 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
// Setup WebAssembly
Handle<String> name = v8_str(isolate, "WebAssembly");
NewFunctionArgs args = NewFunctionArgs::ForFunctionWithoutCode(
name, isolate->strict_function_map(), LanguageMode::kStrict);
Handle<JSFunction> cons = factory->NewFunction(args);
// Not supposed to be called, hence using the kIllegal builtin as code.
Handle<SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name, Builtins::kIllegal);
info->set_language_mode(LanguageMode::kStrict);
Handle<JSFunction> cons = Factory::JSFunctionBuilder{isolate, info, context}
.set_map(isolate->strict_function_map())
.Build();
JSFunction::SetPrototype(cons, isolate->initial_object_prototype());
Handle<JSObject> webassembly =
factory->NewJSObject(cons, AllocationType::kOld);
......
......@@ -1879,11 +1879,12 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
DCHECK_GE(kMaxInt, jump_table_diff);
jump_table_offset = static_cast<int>(jump_table_diff);
}
Factory* factory = isolate->factory();
const wasm::FunctionSig* sig = instance->module()->functions[func_index].sig;
Handle<Foreign> sig_foreign =
isolate->factory()->NewForeign(reinterpret_cast<Address>(sig));
factory->NewForeign(reinterpret_cast<Address>(sig));
Handle<WasmExportedFunctionData> function_data =
Handle<WasmExportedFunctionData>::cast(isolate->factory()->NewStruct(
Handle<WasmExportedFunctionData>::cast(factory->NewStruct(
WASM_EXPORTED_FUNCTION_DATA_TYPE, AllocationType::kOld));
function_data->set_wrapper_code(*export_wrapper);
function_data->set_instance(*instance);
......@@ -1907,7 +1908,7 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
if (!maybe_name.ToHandle(&name)) {
EmbeddedVector<char, 16> buffer;
int length = SNPrintF(buffer, "%d", func_index);
name = isolate->factory()
name = factory
->NewStringFromOneByte(
Vector<uint8_t>::cast(buffer.SubVector(0, length)))
.ToHandleChecked();
......@@ -1934,15 +1935,22 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
function_map = isolate->strict_function_map();
break;
}
NewFunctionArgs args =
NewFunctionArgs::ForWasm(name, function_data, function_map);
Handle<JSFunction> js_function = isolate->factory()->NewFunction(args);
Handle<NativeContext> context(isolate->native_context());
Handle<SharedFunctionInfo> shared =
factory->NewSharedFunctionInfoForWasmExportedFunction(name,
function_data);
Handle<JSFunction> js_function =
Factory::JSFunctionBuilder{isolate, shared, context}
.set_map(function_map)
.Build();
// According to the spec, exported functions should not have a [[Construct]]
// method. This does not apply to functions exported from asm.js however.
DCHECK_EQ(is_asm_js_module, js_function->IsConstructor());
js_function->shared().set_length(arity);
js_function->shared().set_internal_formal_parameter_count(arity);
js_function->shared().set_script(instance->module_object().script());
shared->set_length(arity);
shared->set_internal_formal_parameter_count(arity);
shared->set_script(instance->module_object().script());
return Handle<WasmExportedFunction>::cast(js_function);
}
......@@ -1995,9 +2003,9 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
Handle<Code> wrapper_code =
compiler::CompileJSToJSWrapper(isolate, sig, nullptr).ToHandleChecked();
Handle<WasmJSFunctionData> function_data =
Handle<WasmJSFunctionData>::cast(isolate->factory()->NewStruct(
WASM_JS_FUNCTION_DATA_TYPE, AllocationType::kOld));
Factory* factory = isolate->factory();
Handle<WasmJSFunctionData> function_data = Handle<WasmJSFunctionData>::cast(
factory->NewStruct(WASM_JS_FUNCTION_DATA_TYPE, AllocationType::kOld));
function_data->set_serialized_return_count(return_count);
function_data->set_serialized_parameter_count(parameter_count);
function_data->set_serialized_signature(*serialized_sig);
......@@ -2027,7 +2035,7 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
function_data->set_wasm_to_js_wrapper_code(*wasm_to_js_wrapper_code);
}
Handle<String> name = isolate->factory()->Function_string();
Handle<String> name = factory->Function_string();
if (callable->IsJSFunction()) {
name = JSFunction::GetName(Handle<JSFunction>::cast(callable));
name = String::Flatten(isolate, name);
......@@ -2035,9 +2043,13 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
Handle<Map> function_map =
Map::Copy(isolate, isolate->wasm_exported_function_map(),
"fresh function map for WasmJSFunction::New");
NewFunctionArgs args =
NewFunctionArgs::ForWasm(name, function_data, function_map);
Handle<JSFunction> js_function = isolate->factory()->NewFunction(args);
Handle<NativeContext> context(isolate->native_context());
Handle<SharedFunctionInfo> shared =
factory->NewSharedFunctionInfoForWasmJSFunction(name, function_data);
Handle<JSFunction> js_function =
Factory::JSFunctionBuilder{isolate, shared, context}
.set_map(function_map)
.Build();
js_function->shared().set_internal_formal_parameter_count(parameter_count);
return Handle<WasmJSFunction>::cast(js_function);
}
......
......@@ -137,10 +137,14 @@ TEST(StressJS) {
v8::Local<v8::Context> env = v8::Context::New(CcTest::isolate());
env->Enter();
NewFunctionArgs args = NewFunctionArgs::ForBuiltin(
factory->function_string(), isolate->sloppy_function_map(),
Builtins::kEmptyFunction);
Handle<JSFunction> function = factory->NewFunction(args);
Handle<NativeContext> context(isolate->native_context());
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfoForBuiltin(
factory->function_string(), Builtins::kEmptyFunction);
info->set_language_mode(LanguageMode::kStrict);
Handle<JSFunction> function =
Factory::JSFunctionBuilder{isolate, info, context}
.set_map(isolate->sloppy_function_map())
.Build();
CHECK(!function->shared().construct_as_builtin());
// Force the creation of an initial map.
......
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