Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index 74073a9b224ae4c6cf9e1220a9c89f0140bb7e2f..cb5ca297ea1113dacbb186247732a26c0e3129c1 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -257,10 +257,12 @@ class Genesis BASE_EMBEDDED { |
function_mode == FUNCTION_WITH_READONLY_PROTOTYPE); |
} |
- Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode); |
+ Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode, |
+ bool add_restricted_props = true); |
void SetFunctionInstanceDescriptor(Handle<Map> map, |
- FunctionMode function_mode); |
+ FunctionMode function_mode, |
+ bool add_restricted_props = true); |
void MakeFunctionInstancePrototypeWritable(); |
Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode, |
@@ -296,6 +298,7 @@ class Genesis BASE_EMBEDDED { |
// prototype, maps. |
Handle<Map> sloppy_function_map_writable_prototype_; |
Handle<Map> strict_function_map_writable_prototype_; |
+ Handle<Map> plain_function_map_writable_prototype_; |
arv (Not doing code reviews)
2015/03/25 13:36:47
Can you rename these. Right now it is not clear ho
caitp (gmail)
2015/03/25 13:42:59
what would be better here? "newstyle_..."? "unpois
|
Handle<JSFunction> strict_poison_function; |
Handle<JSFunction> generator_poison_function; |
@@ -377,8 +380,9 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target, |
} |
-void Genesis::SetFunctionInstanceDescriptor( |
- Handle<Map> map, FunctionMode function_mode) { |
+void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map, |
+ FunctionMode function_mode, |
+ bool add_restricted_props) { |
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; |
Map::EnsureDescriptorSlack(map, size); |
@@ -401,16 +405,16 @@ void Genesis::SetFunctionInstanceDescriptor( |
roc_attribs); |
map->AppendDescriptor(&d); |
} |
- Handle<AccessorInfo> args = |
- Accessors::FunctionArgumentsInfo(isolate(), ro_attribs); |
- { // Add arguments. |
+ if (add_restricted_props) { // Add arguments. |
+ Handle<AccessorInfo> args = |
+ Accessors::FunctionArgumentsInfo(isolate(), ro_attribs); |
AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args, |
ro_attribs); |
map->AppendDescriptor(&d); |
} |
- Handle<AccessorInfo> caller = |
- Accessors::FunctionCallerInfo(isolate(), ro_attribs); |
- { // Add caller. |
+ if (add_restricted_props) { // Add caller. |
arv (Not doing code reviews)
2015/03/25 13:36:47
Maybe
if (add_restricted_props) {
{
...
}
|
+ Handle<AccessorInfo> caller = |
+ Accessors::FunctionCallerInfo(isolate(), ro_attribs); |
AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())), |
caller, ro_attribs); |
map->AppendDescriptor(&d); |
@@ -428,9 +432,10 @@ void Genesis::SetFunctionInstanceDescriptor( |
} |
-Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode) { |
+Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode, |
+ bool add_restricted_props) { |
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
- SetFunctionInstanceDescriptor(map, function_mode); |
+ SetFunctionInstanceDescriptor(map, function_mode, add_restricted_props); |
map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); |
return map; |
} |
@@ -447,6 +452,11 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { |
native_context()->set_sloppy_function_without_prototype_map( |
*function_without_prototype_map); |
+ Handle<Map> plain_function_without_prototype_map = |
+ CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, false); |
+ native_context()->set_plain_function_without_prototype_map( |
+ *plain_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. |
@@ -456,11 +466,16 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { |
native_context()->set_sloppy_function_with_readonly_prototype_map( |
*function_map); |
+ Handle<Map> plain_function_map = |
+ CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, false); |
+ native_context()->set_plain_function_map(*plain_function_map); |
+ |
// The final map for functions. Writeable prototype. |
// This map is installed in MakeFunctionInstancePrototypeWritable. |
sloppy_function_map_writable_prototype_ = |
CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); |
- |
+ plain_function_map_writable_prototype_ = |
+ CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, false); |
Factory* factory = isolate->factory(); |
Handle<String> object_name = factory->Object_string(); |
@@ -526,13 +541,17 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { |
native_context()->sloppy_function_map()->SetPrototype(empty_function); |
native_context()->sloppy_function_without_prototype_map()->SetPrototype( |
empty_function); |
+ native_context()->plain_function_map()->SetPrototype(empty_function); |
+ native_context()->plain_function_without_prototype_map()->SetPrototype( |
+ empty_function); |
sloppy_function_map_writable_prototype_->SetPrototype(empty_function); |
+ plain_function_map_writable_prototype_->SetPrototype(empty_function); |
return empty_function; |
} |
-void Genesis::SetStrictFunctionInstanceDescriptor( |
- Handle<Map> map, FunctionMode function_mode) { |
+void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map, |
+ FunctionMode function_mode) { |
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; |
Map::EnsureDescriptorSlack(map, size); |
@@ -649,8 +668,7 @@ Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() { |
Handle<Map> Genesis::CreateStrictFunctionMap( |
- FunctionMode function_mode, |
- Handle<JSFunction> empty_function) { |
+ FunctionMode function_mode, Handle<JSFunction> empty_function) { |
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
SetStrictFunctionInstanceDescriptor(map, function_mode); |
map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); |
@@ -689,6 +707,7 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
// This map is installed in MakeFunctionInstancePrototypeWritable. |
strict_function_map_writable_prototype_ = |
CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty); |
+ |
// Special map for bound functions. |
Handle<Map> bound_function_map = |
CreateStrictFunctionMap(BOUND_FUNCTION, empty); |
@@ -723,17 +742,6 @@ static void SetAccessors(Handle<Map> map, |
} |
-static void ReplaceAccessors(Handle<Map> map, |
- Handle<String> name, |
- PropertyAttributes attributes, |
- Handle<AccessorPair> accessor_pair) { |
- DescriptorArray* descriptors = map->instance_descriptors(); |
- int idx = descriptors->SearchWithCache(*name, *map); |
- AccessorConstantDescriptor descriptor(name, accessor_pair, attributes); |
- descriptors->Replace(idx, &descriptor); |
-} |
- |
- |
void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { |
SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction()); |
SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction()); |
@@ -2072,43 +2080,9 @@ bool Genesis::InstallNatives() { |
// Create maps for generator functions and their prototypes. Store those |
// maps in the native context. |
Handle<Map> generator_function_map = |
- Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction"); |
+ Map::Copy(plain_function_map_writable_prototype_, "GeneratorFunction"); |
generator_function_map->SetPrototype(generator_function_prototype); |
- native_context()->set_sloppy_generator_function_map( |
- *generator_function_map); |
- |
- // The "arguments" and "caller" instance properties aren't specified, so |
- // technically we could leave them out. They make even less sense for |
- // generators than for functions. Still, the same argument that it makes |
- // sense to keep them around but poisoned in strict mode applies to |
- // generators as well. With poisoned accessors, naive callers can still |
- // iterate over the properties without accessing them. |
- // |
- // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs |
- // in place, and the initial state of the generator function map shares the |
- // accessor pair with sloppy functions. Also the error message should be |
- // different. Also unhappily, we can't use the API accessors to implement |
- // poisoning, because API accessors present themselves as data properties, |
- // not accessor properties, and so getOwnPropertyDescriptor raises an |
- // exception as it tries to get the values. Sadness. |
- Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); |
- PropertyAttributes rw_attribs = |
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
- Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); |
- poison_pair->set_getter(*poison_function); |
- poison_pair->set_setter(*poison_function); |
- ReplaceAccessors(generator_function_map, factory()->arguments_string(), |
- rw_attribs, poison_pair); |
- ReplaceAccessors(generator_function_map, factory()->caller_string(), |
- rw_attribs, poison_pair); |
- |
- Handle<Map> strict_function_map(native_context()->strict_function_map()); |
- Handle<Map> strict_generator_function_map = |
- Map::Copy(strict_function_map, "StrictGeneratorFunction"); |
- // "arguments" and "caller" already poisoned. |
- strict_generator_function_map->SetPrototype(generator_function_prototype); |
- native_context()->set_strict_generator_function_map( |
- *strict_generator_function_map); |
+ native_context()->set_generator_function_map(*generator_function_map); |
Handle<Map> strong_function_map(native_context()->strong_function_map()); |
Handle<Map> strong_generator_function_map = |