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 |