Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bootstrapper.h" | 5 #include "bootstrapper.h" |
| 6 | 6 |
| 7 #include "accessors.h" | 7 #include "accessors.h" |
| 8 #include "isolate-inl.h" | 8 #include "isolate-inl.h" |
| 9 #include "natives.h" | 9 #include "natives.h" |
| 10 #include "snapshot.h" | 10 #include "snapshot.h" |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 | 161 |
| 162 private: | 162 private: |
| 163 Handle<Context> native_context() { return native_context_; } | 163 Handle<Context> native_context() { return native_context_; } |
| 164 | 164 |
| 165 // Creates some basic objects. Used for creating a context from scratch. | 165 // Creates some basic objects. Used for creating a context from scratch. |
| 166 void CreateRoots(); | 166 void CreateRoots(); |
| 167 // Creates the empty function. Used for creating a context from scratch. | 167 // Creates the empty function. Used for creating a context from scratch. |
| 168 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); | 168 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); |
| 169 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 | 169 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 |
| 170 Handle<JSFunction> GetThrowTypeErrorFunction(); | 170 Handle<JSFunction> GetThrowTypeErrorFunction(); |
| 171 // Poison for sloppy generator function arguments/callee. | |
| 172 Handle<JSFunction> GetGeneratorFunctionPoison(); | |
| 171 | 173 |
| 172 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); | 174 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
| 173 | 175 |
| 174 // Make the "arguments" and "caller" properties throw a TypeError on access. | 176 // Make the "arguments" and "caller" properties throw a TypeError on access. |
| 175 void PoisonArgumentsAndCaller(Handle<Map> map); | 177 void PoisonArgumentsAndCaller(Handle<Map> map); |
| 176 | 178 |
| 177 // Creates the global objects using the global and the template passed in | 179 // Creates the global objects using the global and the template passed in |
| 178 // through the API. We call this regardless of whether we are building a | 180 // through the API. We call this regardless of whether we are building a |
| 179 // context from scratch or using a deserialized one from the partial snapshot | 181 // context from scratch or using a deserialized one from the partial snapshot |
| 180 // but in the latter case we don't use the objects it produces directly, as | 182 // but in the latter case we don't use the objects it produces directly, as |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 Isolate* isolate_; | 297 Isolate* isolate_; |
| 296 Handle<Context> result_; | 298 Handle<Context> result_; |
| 297 Handle<Context> native_context_; | 299 Handle<Context> native_context_; |
| 298 | 300 |
| 299 // Function maps. Function maps are created initially with a read only | 301 // Function maps. Function maps are created initially with a read only |
| 300 // prototype for the processing of JS builtins. Later the function maps are | 302 // prototype for the processing of JS builtins. Later the function maps are |
| 301 // replaced in order to make prototype writable. These are the final, writable | 303 // replaced in order to make prototype writable. These are the final, writable |
| 302 // prototype, maps. | 304 // prototype, maps. |
| 303 Handle<Map> sloppy_function_map_writable_prototype_; | 305 Handle<Map> sloppy_function_map_writable_prototype_; |
| 304 Handle<Map> strict_function_map_writable_prototype_; | 306 Handle<Map> strict_function_map_writable_prototype_; |
| 305 Handle<JSFunction> throw_type_error_function; | 307 Handle<JSFunction> throw_type_error_function; |
|
rossberg
2014/05/07 09:19:54
Nit: can we somehow rename this to make it more co
| |
| 308 Handle<JSFunction> generator_function_poison; | |
| 306 | 309 |
| 307 BootstrapperActive active_; | 310 BootstrapperActive active_; |
| 308 friend class Bootstrapper; | 311 friend class Bootstrapper; |
| 309 }; | 312 }; |
| 310 | 313 |
| 311 | 314 |
| 312 void Bootstrapper::Iterate(ObjectVisitor* v) { | 315 void Bootstrapper::Iterate(ObjectVisitor* v) { |
| 313 extensions_cache_.Iterate(v); | 316 extensions_cache_.Iterate(v); |
| 314 v->Synchronize(VisitorSynchronization::kExtensions); | 317 v->Synchronize(VisitorSynchronization::kExtensions); |
| 315 } | 318 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 throw_type_error_function = factory()->NewFunction(name, code); | 581 throw_type_error_function = factory()->NewFunction(name, code); |
| 579 throw_type_error_function->set_map(native_context()->sloppy_function_map()); | 582 throw_type_error_function->set_map(native_context()->sloppy_function_map()); |
| 580 throw_type_error_function->shared()->DontAdaptArguments(); | 583 throw_type_error_function->shared()->DontAdaptArguments(); |
| 581 | 584 |
| 582 JSObject::PreventExtensions(throw_type_error_function).Assert(); | 585 JSObject::PreventExtensions(throw_type_error_function).Assert(); |
| 583 } | 586 } |
| 584 return throw_type_error_function; | 587 return throw_type_error_function; |
| 585 } | 588 } |
| 586 | 589 |
| 587 | 590 |
| 591 Handle<JSFunction> Genesis::GetGeneratorFunctionPoison() { | |
| 592 if (generator_function_poison.is_null()) { | |
| 593 Handle<String> name = factory()->InternalizeOneByteString( | |
| 594 STATIC_ASCII_VECTOR("ThrowTypeError")); | |
| 595 Handle<Code> code(isolate()->builtins()->builtin( | |
| 596 Builtins::kGeneratorPoisonPill)); | |
| 597 generator_function_poison = factory()->NewFunction(name, code); | |
| 598 generator_function_poison->set_map(native_context()->sloppy_function_map()); | |
| 599 generator_function_poison->shared()->DontAdaptArguments(); | |
| 600 | |
| 601 JSObject::PreventExtensions(generator_function_poison).Assert(); | |
| 602 } | |
| 603 return generator_function_poison; | |
| 604 } | |
| 605 | |
| 606 | |
| 588 Handle<Map> Genesis::CreateStrictFunctionMap( | 607 Handle<Map> Genesis::CreateStrictFunctionMap( |
| 589 PrototypePropertyMode prototype_mode, | 608 PrototypePropertyMode prototype_mode, |
| 590 Handle<JSFunction> empty_function) { | 609 Handle<JSFunction> empty_function) { |
| 591 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 610 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 592 SetStrictFunctionInstanceDescriptor(map, prototype_mode); | 611 SetStrictFunctionInstanceDescriptor(map, prototype_mode); |
| 593 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); | 612 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
| 594 map->set_prototype(*empty_function); | 613 map->set_prototype(*empty_function); |
| 595 return map; | 614 return map; |
| 596 } | 615 } |
| 597 | 616 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 626 Handle<String> name, | 645 Handle<String> name, |
| 627 Handle<JSFunction> func) { | 646 Handle<JSFunction> func) { |
| 628 DescriptorArray* descs = map->instance_descriptors(); | 647 DescriptorArray* descs = map->instance_descriptors(); |
| 629 int number = descs->SearchWithCache(*name, *map); | 648 int number = descs->SearchWithCache(*name, *map); |
| 630 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); | 649 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); |
| 631 accessors->set_getter(*func); | 650 accessors->set_getter(*func); |
| 632 accessors->set_setter(*func); | 651 accessors->set_setter(*func); |
| 633 } | 652 } |
| 634 | 653 |
| 635 | 654 |
| 655 static void ReplaceAccessors(Handle<Map> map, | |
| 656 Handle<String> name, | |
| 657 PropertyAttributes attributes, | |
| 658 Handle<AccessorPair> accessor_pair) { | |
| 659 DescriptorArray* descriptors = map->instance_descriptors(); | |
| 660 int idx = descriptors->SearchWithCache(*name, *map); | |
| 661 CallbacksDescriptor descriptor(name, accessor_pair, attributes); | |
| 662 descriptors->Replace(idx, &descriptor); | |
| 663 } | |
| 664 | |
| 665 | |
| 636 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { | 666 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { |
| 637 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction()); | 667 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction()); |
| 638 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); | 668 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); |
| 639 } | 669 } |
| 640 | 670 |
| 641 | 671 |
| 642 static void AddToWeakNativeContextList(Context* context) { | 672 static void AddToWeakNativeContextList(Context* context) { |
| 643 ASSERT(context->IsNativeContext()); | 673 ASSERT(context->IsNativeContext()); |
| 644 Heap* heap = context->GetIsolate()->heap(); | 674 Heap* heap = context->GetIsolate()->heap(); |
| 645 #ifdef DEBUG | 675 #ifdef DEBUG |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1359 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, | 1389 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, |
| 1360 generator_object_prototype, Builtins::kIllegal, | 1390 generator_object_prototype, Builtins::kIllegal, |
| 1361 false, false); | 1391 false, false); |
| 1362 InstallFunction(builtins, "GeneratorFunction", | 1392 InstallFunction(builtins, "GeneratorFunction", |
| 1363 JS_FUNCTION_TYPE, JSFunction::kSize, | 1393 JS_FUNCTION_TYPE, JSFunction::kSize, |
| 1364 generator_function_prototype, Builtins::kIllegal, | 1394 generator_function_prototype, Builtins::kIllegal, |
| 1365 false, false); | 1395 false, false); |
| 1366 | 1396 |
| 1367 // Create maps for generator functions and their prototypes. Store those | 1397 // Create maps for generator functions and their prototypes. Store those |
| 1368 // maps in the native context. | 1398 // maps in the native context. |
| 1369 Handle<Map> function_map(native_context()->sloppy_function_map()); | 1399 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map()); |
| 1370 Handle<Map> generator_function_map = Map::Copy(function_map); | 1400 Handle<Map> generator_function_map = Map::Copy(sloppy_function_map); |
| 1371 generator_function_map->set_prototype(*generator_function_prototype); | 1401 generator_function_map->set_prototype(*generator_function_prototype); |
| 1372 native_context()->set_sloppy_generator_function_map( | 1402 native_context()->set_sloppy_generator_function_map( |
| 1373 *generator_function_map); | 1403 *generator_function_map); |
| 1374 | 1404 |
| 1375 Handle<Map> strict_mode_function_map( | 1405 // The "arguments" and "caller" instance properties aren't specified, so |
| 1376 native_context()->strict_function_map()); | 1406 // technically we could leave them out. They make even less sense for |
| 1407 // generators than for functions. Still, the same argument that it makes | |
| 1408 // sense to keep them around but poisoned in strict mode applies to | |
| 1409 // generators as well. With poisoned accessors, naive callers can still | |
| 1410 // iterate over the properties without accessing them. | |
| 1411 // | |
| 1412 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs | |
| 1413 // in place, and the initial state of the generator function map shares the | |
| 1414 // accessor pair with sloppy functions. Also the error message should be | |
| 1415 // different. Also unhappily, we can't use the API accessors to implement | |
| 1416 // poisoning, because API accessors present themselves as data properties, | |
| 1417 // not accessor properties, and so getOwnPropertyDescriptor raises an | |
| 1418 // exception as it tries to get the values. Sadness. | |
| 1419 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); | |
| 1420 PropertyAttributes rw_attribs = | |
| 1421 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | |
| 1422 poison_pair->set_getter(*GetGeneratorFunctionPoison()); | |
| 1423 poison_pair->set_setter(*GetGeneratorFunctionPoison()); | |
| 1424 ReplaceAccessors(generator_function_map, factory()->arguments_string(), | |
| 1425 rw_attribs, poison_pair); | |
| 1426 ReplaceAccessors(generator_function_map, factory()->caller_string(), | |
| 1427 rw_attribs, poison_pair); | |
| 1428 | |
| 1429 Handle<Map> strict_function_map(native_context()->strict_function_map()); | |
| 1377 Handle<Map> strict_mode_generator_function_map = | 1430 Handle<Map> strict_mode_generator_function_map = |
|
rossberg
2014/05/07 09:19:54
Nit: for consistency, drop _mode_ here, too.
| |
| 1378 Map::Copy(strict_mode_function_map); | 1431 Map::Copy(strict_function_map); |
| 1432 // "arguments" and "caller" already poisoned. | |
| 1379 strict_mode_generator_function_map->set_prototype( | 1433 strict_mode_generator_function_map->set_prototype( |
| 1380 *generator_function_prototype); | 1434 *generator_function_prototype); |
| 1381 native_context()->set_strict_generator_function_map( | 1435 native_context()->set_strict_generator_function_map( |
| 1382 *strict_mode_generator_function_map); | 1436 *strict_mode_generator_function_map); |
| 1383 | 1437 |
| 1384 Handle<JSFunction> object_function(native_context()->object_function()); | 1438 Handle<JSFunction> object_function(native_context()->object_function()); |
| 1385 Handle<Map> generator_object_prototype_map = Map::Create( | 1439 Handle<Map> generator_object_prototype_map = Map::Create( |
| 1386 object_function, 0); | 1440 object_function, 0); |
| 1387 generator_object_prototype_map->set_prototype( | 1441 generator_object_prototype_map->set_prototype( |
| 1388 *generator_object_prototype); | 1442 *generator_object_prototype); |
| (...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2698 return from + sizeof(NestingCounterType); | 2752 return from + sizeof(NestingCounterType); |
| 2699 } | 2753 } |
| 2700 | 2754 |
| 2701 | 2755 |
| 2702 // Called when the top-level V8 mutex is destroyed. | 2756 // Called when the top-level V8 mutex is destroyed. |
| 2703 void Bootstrapper::FreeThreadResources() { | 2757 void Bootstrapper::FreeThreadResources() { |
| 2704 ASSERT(!IsActive()); | 2758 ASSERT(!IsActive()); |
| 2705 } | 2759 } |
| 2706 | 2760 |
| 2707 } } // namespace v8::internal | 2761 } } // namespace v8::internal |
| OLD | NEW |