| 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 Handle<Context> result() { return result_; } | 160 Handle<Context> result() { return result_; } |
| 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> GetStrictPoisonFunction(); |
| 171 // Poison for sloppy generator function arguments/callee. |
| 172 Handle<JSFunction> GetGeneratorPoisonFunction(); |
| 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> strict_poison_function; |
| 308 Handle<JSFunction> generator_poison_function; |
| 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 Handle<AccessorInfo> prototype = | 565 Handle<AccessorInfo> prototype = |
| 563 Accessors::FunctionPrototypeInfo(isolate(), attribs); | 566 Accessors::FunctionPrototypeInfo(isolate(), attribs); |
| 564 CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())), | 567 CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())), |
| 565 prototype, attribs); | 568 prototype, attribs); |
| 566 map->AppendDescriptor(&d); | 569 map->AppendDescriptor(&d); |
| 567 } | 570 } |
| 568 } | 571 } |
| 569 | 572 |
| 570 | 573 |
| 571 // ECMAScript 5th Edition, 13.2.3 | 574 // ECMAScript 5th Edition, 13.2.3 |
| 572 Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() { | 575 Handle<JSFunction> Genesis::GetStrictPoisonFunction() { |
| 573 if (throw_type_error_function.is_null()) { | 576 if (strict_poison_function.is_null()) { |
| 574 Handle<String> name = factory()->InternalizeOneByteString( | 577 Handle<String> name = factory()->InternalizeOneByteString( |
| 575 STATIC_ASCII_VECTOR("ThrowTypeError")); | 578 STATIC_ASCII_VECTOR("ThrowTypeError")); |
| 576 Handle<Code> code(isolate()->builtins()->builtin( | 579 Handle<Code> code(isolate()->builtins()->builtin( |
| 577 Builtins::kStrictModePoisonPill)); | 580 Builtins::kStrictModePoisonPill)); |
| 578 throw_type_error_function = factory()->NewFunction(name, code); | 581 strict_poison_function = factory()->NewFunction(name, code); |
| 579 throw_type_error_function->set_map(native_context()->sloppy_function_map()); | 582 strict_poison_function->set_map(native_context()->sloppy_function_map()); |
| 580 throw_type_error_function->shared()->DontAdaptArguments(); | 583 strict_poison_function->shared()->DontAdaptArguments(); |
| 581 | 584 |
| 582 JSObject::PreventExtensions(throw_type_error_function).Assert(); | 585 JSObject::PreventExtensions(strict_poison_function).Assert(); |
| 583 } | 586 } |
| 584 return throw_type_error_function; | 587 return strict_poison_function; |
| 585 } | 588 } |
| 586 | 589 |
| 587 | 590 |
| 591 Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() { |
| 592 if (generator_poison_function.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_poison_function = factory()->NewFunction(name, code); |
| 598 generator_poison_function->set_map(native_context()->sloppy_function_map()); |
| 599 generator_poison_function->shared()->DontAdaptArguments(); |
| 600 |
| 601 JSObject::PreventExtensions(generator_poison_function).Assert(); |
| 602 } |
| 603 return generator_poison_function; |
| 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(), GetStrictPoisonFunction()); |
| 638 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); | 668 SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction()); |
| 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 |
| 646 { // NOLINT | 676 { // NOLINT |
| 647 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); | 677 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); |
| 648 // Check that context is not in the list yet. | 678 // Check that context is not in the list yet. |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 } | 1185 } |
| 1156 | 1186 |
| 1157 { // --- strict mode arguments boilerplate | 1187 { // --- strict mode arguments boilerplate |
| 1158 const PropertyAttributes attributes = | 1188 const PropertyAttributes attributes = |
| 1159 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 1189 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 1160 | 1190 |
| 1161 // Create the ThrowTypeError functions. | 1191 // Create the ThrowTypeError functions. |
| 1162 Handle<AccessorPair> callee = factory->NewAccessorPair(); | 1192 Handle<AccessorPair> callee = factory->NewAccessorPair(); |
| 1163 Handle<AccessorPair> caller = factory->NewAccessorPair(); | 1193 Handle<AccessorPair> caller = factory->NewAccessorPair(); |
| 1164 | 1194 |
| 1165 Handle<JSFunction> throw_function = | 1195 Handle<JSFunction> poison = GetStrictPoisonFunction(); |
| 1166 GetThrowTypeErrorFunction(); | |
| 1167 | 1196 |
| 1168 // Install the ThrowTypeError functions. | 1197 // Install the ThrowTypeError functions. |
| 1169 callee->set_getter(*throw_function); | 1198 callee->set_getter(*poison); |
| 1170 callee->set_setter(*throw_function); | 1199 callee->set_setter(*poison); |
| 1171 caller->set_getter(*throw_function); | 1200 caller->set_getter(*poison); |
| 1172 caller->set_setter(*throw_function); | 1201 caller->set_setter(*poison); |
| 1173 | 1202 |
| 1174 // Create the map. Allocate one in-object field for length. | 1203 // Create the map. Allocate one in-object field for length. |
| 1175 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, | 1204 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, |
| 1176 Heap::kStrictArgumentsObjectSize); | 1205 Heap::kStrictArgumentsObjectSize); |
| 1177 // Create the descriptor array for the arguments object. | 1206 // Create the descriptor array for the arguments object. |
| 1178 Map::EnsureDescriptorSlack(map, 3); | 1207 Map::EnsureDescriptorSlack(map, 3); |
| 1179 | 1208 |
| 1180 { // length | 1209 { // length |
| 1181 FieldDescriptor d( | 1210 FieldDescriptor d( |
| 1182 factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); | 1211 factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1359 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, | 1388 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, |
| 1360 generator_object_prototype, Builtins::kIllegal, | 1389 generator_object_prototype, Builtins::kIllegal, |
| 1361 false, false); | 1390 false, false); |
| 1362 InstallFunction(builtins, "GeneratorFunction", | 1391 InstallFunction(builtins, "GeneratorFunction", |
| 1363 JS_FUNCTION_TYPE, JSFunction::kSize, | 1392 JS_FUNCTION_TYPE, JSFunction::kSize, |
| 1364 generator_function_prototype, Builtins::kIllegal, | 1393 generator_function_prototype, Builtins::kIllegal, |
| 1365 false, false); | 1394 false, false); |
| 1366 | 1395 |
| 1367 // Create maps for generator functions and their prototypes. Store those | 1396 // Create maps for generator functions and their prototypes. Store those |
| 1368 // maps in the native context. | 1397 // maps in the native context. |
| 1369 Handle<Map> function_map(native_context()->sloppy_function_map()); | 1398 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map()); |
| 1370 Handle<Map> generator_function_map = Map::Copy(function_map); | 1399 Handle<Map> generator_function_map = Map::Copy(sloppy_function_map); |
| 1371 generator_function_map->set_prototype(*generator_function_prototype); | 1400 generator_function_map->set_prototype(*generator_function_prototype); |
| 1372 native_context()->set_sloppy_generator_function_map( | 1401 native_context()->set_sloppy_generator_function_map( |
| 1373 *generator_function_map); | 1402 *generator_function_map); |
| 1374 | 1403 |
| 1375 Handle<Map> strict_mode_function_map( | 1404 // The "arguments" and "caller" instance properties aren't specified, so |
| 1376 native_context()->strict_function_map()); | 1405 // technically we could leave them out. They make even less sense for |
| 1377 Handle<Map> strict_mode_generator_function_map = | 1406 // generators than for functions. Still, the same argument that it makes |
| 1378 Map::Copy(strict_mode_function_map); | 1407 // sense to keep them around but poisoned in strict mode applies to |
| 1379 strict_mode_generator_function_map->set_prototype( | 1408 // generators as well. With poisoned accessors, naive callers can still |
| 1380 *generator_function_prototype); | 1409 // iterate over the properties without accessing them. |
| 1410 // |
| 1411 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs |
| 1412 // in place, and the initial state of the generator function map shares the |
| 1413 // accessor pair with sloppy functions. Also the error message should be |
| 1414 // different. Also unhappily, we can't use the API accessors to implement |
| 1415 // poisoning, because API accessors present themselves as data properties, |
| 1416 // not accessor properties, and so getOwnPropertyDescriptor raises an |
| 1417 // exception as it tries to get the values. Sadness. |
| 1418 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); |
| 1419 PropertyAttributes rw_attribs = |
| 1420 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
| 1421 poison_pair->set_getter(*GetGeneratorPoisonFunction()); |
| 1422 poison_pair->set_setter(*GetGeneratorPoisonFunction()); |
| 1423 ReplaceAccessors(generator_function_map, factory()->arguments_string(), |
| 1424 rw_attribs, poison_pair); |
| 1425 ReplaceAccessors(generator_function_map, factory()->caller_string(), |
| 1426 rw_attribs, poison_pair); |
| 1427 |
| 1428 Handle<Map> strict_function_map(native_context()->strict_function_map()); |
| 1429 Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map); |
| 1430 // "arguments" and "caller" already poisoned. |
| 1431 strict_generator_function_map->set_prototype(*generator_function_prototype); |
| 1381 native_context()->set_strict_generator_function_map( | 1432 native_context()->set_strict_generator_function_map( |
| 1382 *strict_mode_generator_function_map); | 1433 *strict_generator_function_map); |
| 1383 | 1434 |
| 1384 Handle<JSFunction> object_function(native_context()->object_function()); | 1435 Handle<JSFunction> object_function(native_context()->object_function()); |
| 1385 Handle<Map> generator_object_prototype_map = Map::Create( | 1436 Handle<Map> generator_object_prototype_map = Map::Create( |
| 1386 object_function, 0); | 1437 object_function, 0); |
| 1387 generator_object_prototype_map->set_prototype( | 1438 generator_object_prototype_map->set_prototype( |
| 1388 *generator_object_prototype); | 1439 *generator_object_prototype); |
| 1389 native_context()->set_generator_object_prototype_map( | 1440 native_context()->set_generator_object_prototype_map( |
| 1390 *generator_object_prototype_map); | 1441 *generator_object_prototype_map); |
| 1391 } | 1442 } |
| 1392 | 1443 |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2698 return from + sizeof(NestingCounterType); | 2749 return from + sizeof(NestingCounterType); |
| 2699 } | 2750 } |
| 2700 | 2751 |
| 2701 | 2752 |
| 2702 // Called when the top-level V8 mutex is destroyed. | 2753 // Called when the top-level V8 mutex is destroyed. |
| 2703 void Bootstrapper::FreeThreadResources() { | 2754 void Bootstrapper::FreeThreadResources() { |
| 2704 ASSERT(!IsActive()); | 2755 ASSERT(!IsActive()); |
| 2705 } | 2756 } |
| 2706 | 2757 |
| 2707 } } // namespace v8::internal | 2758 } } // namespace v8::internal |
| OLD | NEW |