Chromium Code Reviews| 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 = |