Commit e01fef39 authored by jochen's avatar jochen Committed by Commit bot

Move function map creation code from boostrapper to factory

I want to use those methods from ApiNatives so move them to a shared
location.

BUG=
R=verwaest@chromium.org

Review-Url: https://codereview.chromium.org/2156153002
Cr-Commit-Position: refs/heads/master@{#37843}
parent 02ba2441
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/factory.h" #include "src/factory.h"
#include "src/accessors.h"
#include "src/allocation-site-scopes.h" #include "src/allocation-site-scopes.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
...@@ -2395,5 +2396,121 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) { ...@@ -2395,5 +2396,121 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) {
return Handle<String>::null(); return Handle<String>::null();
} }
Handle<Map> Factory::CreateSloppyFunctionMap(FunctionMode function_mode) {
Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetFunctionInstanceDescriptor(map, function_mode);
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable();
return map;
}
void Factory::SetFunctionInstanceDescriptor(Handle<Map> map,
FunctionMode function_mode) {
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
Map::EnsureDescriptorSlack(map, size);
PropertyAttributes ro_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
PropertyAttributes roc_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
Handle<AccessorInfo> length =
Accessors::FunctionLengthInfo(isolate(), roc_attribs);
{ // Add length.
AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
length, roc_attribs);
map->AppendDescriptor(&d);
}
STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
Handle<AccessorInfo> name =
Accessors::FunctionNameInfo(isolate(), ro_attribs);
{ // Add name.
AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
roc_attribs);
map->AppendDescriptor(&d);
}
Handle<AccessorInfo> args =
Accessors::FunctionArgumentsInfo(isolate(), ro_attribs);
{ // Add arguments.
AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args,
ro_attribs);
map->AppendDescriptor(&d);
}
Handle<AccessorInfo> caller =
Accessors::FunctionCallerInfo(isolate(), ro_attribs);
{ // Add caller.
AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())),
caller, ro_attribs);
map->AppendDescriptor(&d);
}
if (IsFunctionModeWithPrototype(function_mode)) {
if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY);
}
Handle<AccessorInfo> prototype =
Accessors::FunctionPrototypeInfo(isolate(), ro_attribs);
AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
prototype, ro_attribs);
map->AppendDescriptor(&d);
}
}
Handle<Map> Factory::CreateStrictFunctionMap(
FunctionMode function_mode, Handle<JSFunction> empty_function) {
Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrictFunctionInstanceDescriptor(map, function_mode);
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable();
Map::SetPrototype(map, empty_function);
return map;
}
void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
FunctionMode function_mode) {
int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2;
Map::EnsureDescriptorSlack(map, size);
PropertyAttributes rw_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
PropertyAttributes ro_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
PropertyAttributes roc_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
function_mode == FUNCTION_WITHOUT_PROTOTYPE);
STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
{ // Add length.
Handle<AccessorInfo> length =
Accessors::FunctionLengthInfo(isolate(), roc_attribs);
AccessorConstantDescriptor d(handle(Name::cast(length->name())), length,
roc_attribs);
map->AppendDescriptor(&d);
}
STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
{ // Add name.
Handle<AccessorInfo> name =
Accessors::FunctionNameInfo(isolate(), roc_attribs);
AccessorConstantDescriptor d(handle(Name::cast(name->name())), name,
roc_attribs);
map->AppendDescriptor(&d);
}
if (IsFunctionModeWithPrototype(function_mode)) {
// Add prototype.
PropertyAttributes attribs =
function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
: ro_attribs;
Handle<AccessorInfo> prototype =
Accessors::FunctionPrototypeInfo(isolate(), attribs);
AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
prototype, attribs);
map->AppendDescriptor(&d);
}
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -12,6 +12,14 @@ ...@@ -12,6 +12,14 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
enum FunctionMode {
// With prototype.
FUNCTION_WITH_WRITEABLE_PROTOTYPE,
FUNCTION_WITH_READONLY_PROTOTYPE,
// Without prototype.
FUNCTION_WITHOUT_PROTOTYPE
};
// Interface for handle based allocation. // Interface for handle based allocation.
class Factory final { class Factory final {
public: public:
...@@ -644,6 +652,16 @@ class Factory final { ...@@ -644,6 +652,16 @@ class Factory final {
MaybeHandle<Code> code, MaybeHandle<Code> code,
bool is_constructor); bool is_constructor);
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
}
Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
Handle<JSFunction> empty_function);
// Allocates a new JSMessageObject object. // Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject(MessageTemplate::Template message, Handle<JSMessageObject> NewJSMessageObject(MessageTemplate::Template message,
Handle<Object> argument, Handle<Object> argument,
...@@ -717,6 +735,12 @@ class Factory final { ...@@ -717,6 +735,12 @@ class Factory final {
// Create a JSArray with no elements and no length. // Create a JSArray with no elements and no length.
Handle<JSArray> NewJSArray(ElementsKind elements_kind, Handle<JSArray> NewJSArray(ElementsKind elements_kind,
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
void SetFunctionInstanceDescriptor(Handle<Map> map,
FunctionMode function_mode);
void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
FunctionMode function_mode);
}; };
} // namespace internal } // namespace internal
......
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