Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index 19a4394d3f658b3c00078ba47897d231c94321b2..b5a07c4a12320bda01c566b105241cc260dbd6fe 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -268,6 +268,11 @@ class Genesis BASE_EMBEDDED { |
ADD_WRITEABLE_PROTOTYPE |
}; |
+ enum ForBoundFunctionMode { |
Toon Verwaest
2014/06/12 21:53:35
I'd rather name this
enum FunctionMapMode {
REG
Jakob Kummerow
2014/06/13 11:43:13
Done.
|
+ FOR_REGULAR_FUNCTION, |
+ FOR_BOUND_FUNCTION |
+ }; |
+ |
Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); |
void SetFunctionInstanceDescriptor(Handle<Map> map, |
@@ -276,10 +281,12 @@ class Genesis BASE_EMBEDDED { |
Handle<Map> CreateStrictFunctionMap( |
PrototypePropertyMode prototype_mode, |
- Handle<JSFunction> empty_function); |
+ Handle<JSFunction> empty_function, |
+ ForBoundFunctionMode bound_mode = FOR_REGULAR_FUNCTION); |
void SetStrictFunctionInstanceDescriptor(Handle<Map> map, |
- PrototypePropertyMode propertyMode); |
+ PrototypePropertyMode propertyMode, |
+ ForBoundFunctionMode bound_mode); |
static bool CompileBuiltin(Isolate* isolate, int index); |
static bool CompileExperimentalBuiltin(Isolate* isolate, int index); |
@@ -523,7 +530,8 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { |
void Genesis::SetStrictFunctionInstanceDescriptor( |
- Handle<Map> map, PrototypePropertyMode prototypeMode) { |
+ Handle<Map> map, PrototypePropertyMode prototypeMode, |
+ ForBoundFunctionMode bound_mode) { |
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; |
Map::EnsureDescriptorSlack(map, size); |
@@ -534,12 +542,20 @@ void Genesis::SetStrictFunctionInstanceDescriptor( |
PropertyAttributes ro_attribs = |
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
- Handle<AccessorInfo> length = |
- Accessors::FunctionLengthInfo(isolate(), ro_attribs); |
- { // Add length. |
+ // Add length. |
+ if (bound_mode == FOR_REGULAR_FUNCTION) { |
+ Handle<AccessorInfo> length = |
+ Accessors::FunctionLengthInfo(isolate(), ro_attribs); |
CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())), |
length, ro_attribs); |
map->AppendDescriptor(&d); |
+ } else { |
+ ASSERT(bound_mode == FOR_BOUND_FUNCTION); |
+ Handle<String> length_string = isolate()->factory()->length_string(); |
+ PropertyAttributes attr = |
+ static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); |
+ FieldDescriptor d(length_string, 0, attr, Representation::Tagged()); |
+ map->AppendDescriptor(&d); |
} |
Handle<AccessorInfo> name = |
Accessors::FunctionNameInfo(isolate(), ro_attribs); |
@@ -606,9 +622,10 @@ Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() { |
Handle<Map> Genesis::CreateStrictFunctionMap( |
PrototypePropertyMode prototype_mode, |
- Handle<JSFunction> empty_function) { |
+ Handle<JSFunction> empty_function, |
+ ForBoundFunctionMode bound_mode) { |
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
- SetStrictFunctionInstanceDescriptor(map, prototype_mode); |
+ SetStrictFunctionInstanceDescriptor(map, prototype_mode, bound_mode); |
map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
map->set_prototype(*empty_function); |
return map; |
@@ -633,11 +650,16 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
// This map is installed in MakeFunctionInstancePrototypeWritable. |
strict_function_map_writable_prototype_ = |
CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty); |
+ // Special map for bound functions. |
+ Handle<Map> bound_function_map = |
+ CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty, FOR_BOUND_FUNCTION); |
+ native_context()->set_bound_function_map(*bound_function_map); |
// Complete the callbacks. |
PoisonArgumentsAndCaller(strict_function_without_prototype_map); |
PoisonArgumentsAndCaller(strict_function_map); |
PoisonArgumentsAndCaller(strict_function_map_writable_prototype_); |
+ PoisonArgumentsAndCaller(bound_function_map); |
} |