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 "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/extensions/externalize-string-extension.h" | 10 #include "src/extensions/externalize-string-extension.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 Handle<Context> result() { return result_; } | 128 Handle<Context> result() { return result_; } |
129 | 129 |
130 private: | 130 private: |
131 Handle<Context> native_context() { return native_context_; } | 131 Handle<Context> native_context() { return native_context_; } |
132 | 132 |
133 // Creates some basic objects. Used for creating a context from scratch. | 133 // Creates some basic objects. Used for creating a context from scratch. |
134 void CreateRoots(); | 134 void CreateRoots(); |
135 // Creates the empty function. Used for creating a context from scratch. | 135 // Creates the empty function. Used for creating a context from scratch. |
136 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); | 136 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); |
137 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 | 137 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 |
138 Handle<JSFunction> GetStrictPoisonFunction(); | 138 Handle<JSFunction> GetRestrictedFunctionPropertiesThrower(); |
139 // Poison for sloppy generator function arguments/callee. | 139 Handle<JSFunction> GetStrictArgumentsPoisonFunction(); |
140 Handle<JSFunction> GetGeneratorPoisonFunction(); | |
141 | 140 |
142 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); | 141 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
143 void CreateStrongModeFunctionMaps(Handle<JSFunction> empty); | 142 void CreateStrongModeFunctionMaps(Handle<JSFunction> empty); |
144 | 143 |
145 // Make the "arguments" and "caller" properties throw a TypeError on access. | 144 // Make the "arguments" and "caller" properties throw a TypeError on access. |
146 void PoisonArgumentsAndCaller(Handle<Map> map); | 145 void AddRestrictedFunctionProperties(Handle<Map> map); |
147 | 146 |
148 // Creates the global objects using the global proxy and the template passed | 147 // Creates the global objects using the global proxy and the template passed |
149 // in through the API. We call this regardless of whether we are building a | 148 // in through the API. We call this regardless of whether we are building a |
150 // context from scratch or using a deserialized one from the partial snapshot | 149 // context from scratch or using a deserialized one from the partial snapshot |
151 // but in the latter case we don't use the objects it produces directly, as | 150 // but in the latter case we don't use the objects it produces directly, as |
152 // we have to used the deserialized ones that are linked together with the | 151 // we have to used the deserialized ones that are linked together with the |
153 // rest of the context snapshot. | 152 // rest of the context snapshot. |
154 Handle<GlobalObject> CreateNewGlobals( | 153 Handle<GlobalObject> CreateNewGlobals( |
155 v8::Handle<v8::ObjectTemplate> global_proxy_template, | 154 v8::Handle<v8::ObjectTemplate> global_proxy_template, |
156 Handle<JSGlobalProxy> global_proxy); | 155 Handle<JSGlobalProxy> global_proxy); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 Handle<Context> result_; | 289 Handle<Context> result_; |
291 Handle<Context> native_context_; | 290 Handle<Context> native_context_; |
292 | 291 |
293 // Function maps. Function maps are created initially with a read only | 292 // Function maps. Function maps are created initially with a read only |
294 // prototype for the processing of JS builtins. Later the function maps are | 293 // prototype for the processing of JS builtins. Later the function maps are |
295 // replaced in order to make prototype writable. These are the final, writable | 294 // replaced in order to make prototype writable. These are the final, writable |
296 // prototype, maps. | 295 // prototype, maps. |
297 Handle<Map> sloppy_function_map_writable_prototype_; | 296 Handle<Map> sloppy_function_map_writable_prototype_; |
298 Handle<Map> strict_function_map_writable_prototype_; | 297 Handle<Map> strict_function_map_writable_prototype_; |
299 Handle<JSFunction> strict_poison_function; | 298 Handle<JSFunction> strict_poison_function; |
300 Handle<JSFunction> generator_poison_function; | 299 Handle<JSFunction> restricted_function_properties_thrower; |
301 | 300 |
302 BootstrapperActive active_; | 301 BootstrapperActive active_; |
303 friend class Bootstrapper; | 302 friend class Bootstrapper; |
304 }; | 303 }; |
305 | 304 |
306 | 305 |
307 void Bootstrapper::Iterate(ObjectVisitor* v) { | 306 void Bootstrapper::Iterate(ObjectVisitor* v) { |
308 extensions_cache_.Iterate(v); | 307 extensions_cache_.Iterate(v); |
309 v->Synchronize(VisitorSynchronization::kExtensions); | 308 v->Synchronize(VisitorSynchronization::kExtensions); |
310 } | 309 } |
(...skipping 29 matching lines...) Expand all Loading... |
340 global_proxy->set_native_context(*factory->null_value()); | 339 global_proxy->set_native_context(*factory->null_value()); |
341 SetObjectPrototype(global_proxy, factory->null_value()); | 340 SetObjectPrototype(global_proxy, factory->null_value()); |
342 global_proxy->map()->SetConstructor(*factory->null_value()); | 341 global_proxy->map()->SetConstructor(*factory->null_value()); |
343 if (FLAG_track_detached_contexts) { | 342 if (FLAG_track_detached_contexts) { |
344 env->GetIsolate()->AddDetachedContext(env); | 343 env->GetIsolate()->AddDetachedContext(env); |
345 } | 344 } |
346 } | 345 } |
347 | 346 |
348 | 347 |
349 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, | 348 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, |
350 const char* name, | 349 const char* name, InstanceType type, |
351 InstanceType type, | |
352 int instance_size, | 350 int instance_size, |
353 MaybeHandle<JSObject> maybe_prototype, | 351 MaybeHandle<JSObject> maybe_prototype, |
354 Builtins::Name call) { | 352 Builtins::Name call, |
| 353 bool strict_function_map = false) { |
355 Isolate* isolate = target->GetIsolate(); | 354 Isolate* isolate = target->GetIsolate(); |
356 Factory* factory = isolate->factory(); | 355 Factory* factory = isolate->factory(); |
357 Handle<String> internalized_name = factory->InternalizeUtf8String(name); | 356 Handle<String> internalized_name = factory->InternalizeUtf8String(name); |
358 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); | 357 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); |
359 Handle<JSObject> prototype; | 358 Handle<JSObject> prototype; |
360 Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype) | 359 static const bool kReadOnlyPrototype = false; |
361 ? factory->NewFunction(internalized_name, call_code, prototype, | 360 static const bool kInstallConstructor = false; |
362 type, instance_size) | 361 Handle<JSFunction> function = |
363 : factory->NewFunctionWithoutPrototype(internalized_name, call_code); | 362 maybe_prototype.ToHandle(&prototype) |
| 363 ? factory->NewFunction(internalized_name, call_code, prototype, type, |
| 364 instance_size, kReadOnlyPrototype, |
| 365 kInstallConstructor, strict_function_map) |
| 366 : factory->NewFunctionWithoutPrototype(internalized_name, call_code, |
| 367 strict_function_map); |
364 PropertyAttributes attributes; | 368 PropertyAttributes attributes; |
365 if (target->IsJSBuiltinsObject()) { | 369 if (target->IsJSBuiltinsObject()) { |
366 attributes = | 370 attributes = |
367 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 371 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
368 } else { | 372 } else { |
369 attributes = DONT_ENUM; | 373 attributes = DONT_ENUM; |
370 } | 374 } |
371 JSObject::AddProperty(target, internalized_name, function, attributes); | 375 JSObject::AddProperty(target, internalized_name, function, attributes); |
372 if (target->IsJSGlobalObject()) { | 376 if (target->IsJSGlobalObject()) { |
373 function->shared()->set_instance_class_name(*internalized_name); | 377 function->shared()->set_instance_class_name(*internalized_name); |
374 } | 378 } |
375 function->shared()->set_native(true); | 379 function->shared()->set_native(true); |
376 return function; | 380 return function; |
377 } | 381 } |
378 | 382 |
379 | 383 |
380 void Genesis::SetFunctionInstanceDescriptor( | 384 void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map, |
381 Handle<Map> map, FunctionMode function_mode) { | 385 FunctionMode function_mode) { |
382 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; | 386 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; |
383 Map::EnsureDescriptorSlack(map, size); | 387 Map::EnsureDescriptorSlack(map, size); |
384 | 388 |
385 PropertyAttributes ro_attribs = | 389 PropertyAttributes ro_attribs = |
386 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 390 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
387 PropertyAttributes roc_attribs = | 391 PropertyAttributes roc_attribs = |
388 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); | 392 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); |
389 | 393 |
390 Handle<AccessorInfo> length = | 394 Handle<AccessorInfo> length = |
391 Accessors::FunctionLengthInfo(isolate(), roc_attribs); | 395 Accessors::FunctionLengthInfo(isolate(), roc_attribs); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 Handle<Map> function_map = | 457 Handle<Map> function_map = |
454 CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE); | 458 CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE); |
455 native_context()->set_sloppy_function_map(*function_map); | 459 native_context()->set_sloppy_function_map(*function_map); |
456 native_context()->set_sloppy_function_with_readonly_prototype_map( | 460 native_context()->set_sloppy_function_with_readonly_prototype_map( |
457 *function_map); | 461 *function_map); |
458 | 462 |
459 // The final map for functions. Writeable prototype. | 463 // The final map for functions. Writeable prototype. |
460 // This map is installed in MakeFunctionInstancePrototypeWritable. | 464 // This map is installed in MakeFunctionInstancePrototypeWritable. |
461 sloppy_function_map_writable_prototype_ = | 465 sloppy_function_map_writable_prototype_ = |
462 CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); | 466 CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); |
463 | |
464 Factory* factory = isolate->factory(); | 467 Factory* factory = isolate->factory(); |
465 | 468 |
466 Handle<String> object_name = factory->Object_string(); | 469 Handle<String> object_name = factory->Object_string(); |
467 | 470 |
468 Handle<JSObject> object_function_prototype; | 471 Handle<JSObject> object_function_prototype; |
469 | 472 |
470 { // --- O b j e c t --- | 473 { // --- O b j e c t --- |
471 Handle<JSFunction> object_fun = factory->NewFunction(object_name); | 474 Handle<JSFunction> object_fun = factory->NewFunction(object_name); |
472 int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount; | 475 int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount; |
473 int instance_size = JSObject::kHeaderSize + kPointerSize * unused; | 476 int instance_size = JSObject::kHeaderSize + kPointerSize * unused; |
(...skipping 30 matching lines...) Expand all Loading... |
504 Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction)); | 507 Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction)); |
505 Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype( | 508 Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype( |
506 empty_string, code); | 509 empty_string, code); |
507 | 510 |
508 // Allocate the function map first and then patch the prototype later | 511 // Allocate the function map first and then patch the prototype later |
509 Handle<Map> empty_function_map = | 512 Handle<Map> empty_function_map = |
510 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE); | 513 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE); |
511 DCHECK(!empty_function_map->is_dictionary_map()); | 514 DCHECK(!empty_function_map->is_dictionary_map()); |
512 empty_function_map->SetPrototype(object_function_prototype); | 515 empty_function_map->SetPrototype(object_function_prototype); |
513 empty_function_map->set_is_prototype_map(true); | 516 empty_function_map->set_is_prototype_map(true); |
| 517 |
514 empty_function->set_map(*empty_function_map); | 518 empty_function->set_map(*empty_function_map); |
515 | 519 |
516 // --- E m p t y --- | 520 // --- E m p t y --- |
517 Handle<String> source = factory->NewStringFromStaticChars("() {}"); | 521 Handle<String> source = factory->NewStringFromStaticChars("() {}"); |
518 Handle<Script> script = factory->NewScript(source); | 522 Handle<Script> script = factory->NewScript(source); |
519 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 523 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
520 empty_function->shared()->set_script(*script); | 524 empty_function->shared()->set_script(*script); |
521 empty_function->shared()->set_start_position(0); | 525 empty_function->shared()->set_start_position(0); |
522 empty_function->shared()->set_end_position(source->length()); | 526 empty_function->shared()->set_end_position(source->length()); |
523 empty_function->shared()->DontAdaptArguments(); | 527 empty_function->shared()->DontAdaptArguments(); |
524 | 528 |
525 // Set prototypes for the function maps. | 529 // Set prototypes for the function maps. |
526 native_context()->sloppy_function_map()->SetPrototype(empty_function); | 530 native_context()->sloppy_function_map()->SetPrototype(empty_function); |
527 native_context()->sloppy_function_without_prototype_map()->SetPrototype( | 531 native_context()->sloppy_function_without_prototype_map()->SetPrototype( |
528 empty_function); | 532 empty_function); |
| 533 |
529 sloppy_function_map_writable_prototype_->SetPrototype(empty_function); | 534 sloppy_function_map_writable_prototype_->SetPrototype(empty_function); |
| 535 |
| 536 // ES6 draft 03-17-2015, section 8.2.2 step 12 |
| 537 AddRestrictedFunctionProperties(empty_function_map); |
| 538 |
530 return empty_function; | 539 return empty_function; |
531 } | 540 } |
532 | 541 |
533 | 542 |
534 void Genesis::SetStrictFunctionInstanceDescriptor( | 543 void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map, |
535 Handle<Map> map, FunctionMode function_mode) { | 544 FunctionMode function_mode) { |
536 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; | 545 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; |
537 Map::EnsureDescriptorSlack(map, size); | 546 Map::EnsureDescriptorSlack(map, size); |
538 | 547 |
539 Handle<AccessorPair> arguments(factory()->NewAccessorPair()); | |
540 Handle<AccessorPair> caller(factory()->NewAccessorPair()); | |
541 PropertyAttributes rw_attribs = | 548 PropertyAttributes rw_attribs = |
542 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 549 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
543 PropertyAttributes ro_attribs = | 550 PropertyAttributes ro_attribs = |
544 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 551 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
545 PropertyAttributes roc_attribs = | 552 PropertyAttributes roc_attribs = |
546 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); | 553 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); |
547 | 554 |
548 // Add length. | 555 // Add length. |
549 if (function_mode == BOUND_FUNCTION) { | 556 if (function_mode == BOUND_FUNCTION) { |
550 Handle<String> length_string = isolate()->factory()->length_string(); | 557 Handle<String> length_string = isolate()->factory()->length_string(); |
551 DataDescriptor d(length_string, 0, ro_attribs, Representation::Tagged()); | 558 DataDescriptor d(length_string, 0, ro_attribs, Representation::Tagged()); |
552 map->AppendDescriptor(&d); | 559 map->AppendDescriptor(&d); |
553 } else { | 560 } else { |
554 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || | 561 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || |
555 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE || | 562 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE || |
556 function_mode == FUNCTION_WITHOUT_PROTOTYPE); | 563 function_mode == FUNCTION_WITHOUT_PROTOTYPE); |
557 Handle<AccessorInfo> length = | 564 Handle<AccessorInfo> length = |
558 Accessors::FunctionLengthInfo(isolate(), roc_attribs); | 565 Accessors::FunctionLengthInfo(isolate(), roc_attribs); |
559 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())), | 566 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())), |
560 length, roc_attribs); | 567 length, roc_attribs); |
561 map->AppendDescriptor(&d); | 568 map->AppendDescriptor(&d); |
562 } | 569 } |
563 Handle<AccessorInfo> name = | 570 Handle<AccessorInfo> name = |
564 Accessors::FunctionNameInfo(isolate(), roc_attribs); | 571 Accessors::FunctionNameInfo(isolate(), roc_attribs); |
565 { // Add name. | 572 { // Add name. |
566 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name, | 573 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name, |
567 roc_attribs); | 574 roc_attribs); |
568 map->AppendDescriptor(&d); | 575 map->AppendDescriptor(&d); |
569 } | 576 } |
570 { // Add arguments. | |
571 AccessorConstantDescriptor d(factory()->arguments_string(), arguments, | |
572 rw_attribs); | |
573 map->AppendDescriptor(&d); | |
574 } | |
575 { // Add caller. | |
576 AccessorConstantDescriptor d(factory()->caller_string(), caller, | |
577 rw_attribs); | |
578 map->AppendDescriptor(&d); | |
579 } | |
580 if (IsFunctionModeWithPrototype(function_mode)) { | 577 if (IsFunctionModeWithPrototype(function_mode)) { |
581 // Add prototype. | 578 // Add prototype. |
582 PropertyAttributes attribs = | 579 PropertyAttributes attribs = |
583 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs | 580 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs |
584 : ro_attribs; | 581 : ro_attribs; |
585 Handle<AccessorInfo> prototype = | 582 Handle<AccessorInfo> prototype = |
586 Accessors::FunctionPrototypeInfo(isolate(), attribs); | 583 Accessors::FunctionPrototypeInfo(isolate(), attribs); |
587 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), | 584 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), |
588 prototype, attribs); | 585 prototype, attribs); |
589 map->AppendDescriptor(&d); | 586 map->AppendDescriptor(&d); |
(...skipping 18 matching lines...) Expand all Loading... |
608 Accessors::FunctionNameInfo(isolate(), ro_attribs); | 605 Accessors::FunctionNameInfo(isolate(), ro_attribs); |
609 { // Add name. | 606 { // Add name. |
610 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name, | 607 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name, |
611 ro_attribs); | 608 ro_attribs); |
612 map->AppendDescriptor(&d); | 609 map->AppendDescriptor(&d); |
613 } | 610 } |
614 } | 611 } |
615 | 612 |
616 | 613 |
617 // ECMAScript 5th Edition, 13.2.3 | 614 // ECMAScript 5th Edition, 13.2.3 |
618 Handle<JSFunction> Genesis::GetStrictPoisonFunction() { | 615 Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() { |
| 616 if (restricted_function_properties_thrower.is_null()) { |
| 617 Handle<String> name = factory()->InternalizeOneByteString( |
| 618 STATIC_CHAR_VECTOR("ThrowTypeError")); |
| 619 Handle<Code> code(isolate()->builtins()->builtin( |
| 620 Builtins::kRestrictedFunctionPropertiesThrower)); |
| 621 restricted_function_properties_thrower = |
| 622 factory()->NewFunctionWithoutPrototype(name, code); |
| 623 restricted_function_properties_thrower->set_map( |
| 624 native_context()->sloppy_function_map()); |
| 625 restricted_function_properties_thrower->shared()->DontAdaptArguments(); |
| 626 |
| 627 JSObject::PreventExtensions(restricted_function_properties_thrower) |
| 628 .Assert(); |
| 629 } |
| 630 return restricted_function_properties_thrower; |
| 631 } |
| 632 |
| 633 |
| 634 Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() { |
619 if (strict_poison_function.is_null()) { | 635 if (strict_poison_function.is_null()) { |
620 Handle<String> name = factory()->InternalizeOneByteString( | 636 Handle<String> name = factory()->InternalizeOneByteString( |
621 STATIC_CHAR_VECTOR("ThrowTypeError")); | 637 STATIC_CHAR_VECTOR("ThrowTypeError")); |
622 Handle<Code> code(isolate()->builtins()->builtin( | 638 Handle<Code> code(isolate()->builtins()->builtin( |
623 Builtins::kStrictModePoisonPill)); | 639 Builtins::kRestrictedStrictArgumentsPropertiesThrower)); |
624 strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code); | 640 strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code); |
625 strict_poison_function->set_map(native_context()->sloppy_function_map()); | 641 strict_poison_function->set_map(native_context()->sloppy_function_map()); |
626 strict_poison_function->shared()->DontAdaptArguments(); | 642 strict_poison_function->shared()->DontAdaptArguments(); |
627 | 643 |
628 JSObject::PreventExtensions(strict_poison_function).Assert(); | 644 JSObject::PreventExtensions(strict_poison_function).Assert(); |
629 } | 645 } |
630 return strict_poison_function; | 646 return strict_poison_function; |
631 } | 647 } |
632 | 648 |
633 | 649 |
634 Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() { | |
635 if (generator_poison_function.is_null()) { | |
636 Handle<String> name = factory()->InternalizeOneByteString( | |
637 STATIC_CHAR_VECTOR("ThrowTypeError")); | |
638 Handle<Code> code(isolate()->builtins()->builtin( | |
639 Builtins::kGeneratorPoisonPill)); | |
640 generator_poison_function = factory()->NewFunctionWithoutPrototype( | |
641 name, code); | |
642 generator_poison_function->set_map(native_context()->sloppy_function_map()); | |
643 generator_poison_function->shared()->DontAdaptArguments(); | |
644 | |
645 JSObject::PreventExtensions(generator_poison_function).Assert(); | |
646 } | |
647 return generator_poison_function; | |
648 } | |
649 | |
650 | |
651 Handle<Map> Genesis::CreateStrictFunctionMap( | 650 Handle<Map> Genesis::CreateStrictFunctionMap( |
652 FunctionMode function_mode, | 651 FunctionMode function_mode, Handle<JSFunction> empty_function) { |
653 Handle<JSFunction> empty_function) { | |
654 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 652 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
655 SetStrictFunctionInstanceDescriptor(map, function_mode); | 653 SetStrictFunctionInstanceDescriptor(map, function_mode); |
656 map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); | 654 map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); |
657 map->SetPrototype(empty_function); | 655 map->SetPrototype(empty_function); |
658 return map; | 656 return map; |
659 } | 657 } |
660 | 658 |
661 | 659 |
662 Handle<Map> Genesis::CreateStrongFunctionMap( | 660 Handle<Map> Genesis::CreateStrongFunctionMap( |
663 Handle<JSFunction> empty_function, bool is_constructor) { | 661 Handle<JSFunction> empty_function, bool is_constructor) { |
(...skipping 18 matching lines...) Expand all Loading... |
682 // only for processing of builtins. | 680 // only for processing of builtins. |
683 // Later the map is replaced with writable prototype map, allocated below. | 681 // Later the map is replaced with writable prototype map, allocated below. |
684 Handle<Map> strict_function_map = | 682 Handle<Map> strict_function_map = |
685 CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty); | 683 CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty); |
686 native_context()->set_strict_function_map(*strict_function_map); | 684 native_context()->set_strict_function_map(*strict_function_map); |
687 | 685 |
688 // The final map for the strict mode functions. Writeable prototype. | 686 // The final map for the strict mode functions. Writeable prototype. |
689 // This map is installed in MakeFunctionInstancePrototypeWritable. | 687 // This map is installed in MakeFunctionInstancePrototypeWritable. |
690 strict_function_map_writable_prototype_ = | 688 strict_function_map_writable_prototype_ = |
691 CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty); | 689 CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty); |
| 690 |
692 // Special map for bound functions. | 691 // Special map for bound functions. |
693 Handle<Map> bound_function_map = | 692 Handle<Map> bound_function_map = |
694 CreateStrictFunctionMap(BOUND_FUNCTION, empty); | 693 CreateStrictFunctionMap(BOUND_FUNCTION, empty); |
695 native_context()->set_bound_function_map(*bound_function_map); | 694 native_context()->set_bound_function_map(*bound_function_map); |
696 | |
697 // Complete the callbacks. | |
698 PoisonArgumentsAndCaller(strict_function_without_prototype_map); | |
699 PoisonArgumentsAndCaller(strict_function_map); | |
700 PoisonArgumentsAndCaller(strict_function_map_writable_prototype_); | |
701 PoisonArgumentsAndCaller(bound_function_map); | |
702 } | 695 } |
703 | 696 |
704 | 697 |
705 void Genesis::CreateStrongModeFunctionMaps(Handle<JSFunction> empty) { | 698 void Genesis::CreateStrongModeFunctionMaps(Handle<JSFunction> empty) { |
706 // Allocate map for strong mode instances, which never have prototypes. | 699 // Allocate map for strong mode instances, which never have prototypes. |
707 Handle<Map> strong_function_map = CreateStrongFunctionMap(empty, false); | 700 Handle<Map> strong_function_map = CreateStrongFunctionMap(empty, false); |
708 native_context()->set_strong_function_map(*strong_function_map); | 701 native_context()->set_strong_function_map(*strong_function_map); |
709 // Constructors do, though. | 702 // Constructors do, though. |
710 Handle<Map> strong_constructor_map = CreateStrongFunctionMap(empty, true); | 703 Handle<Map> strong_constructor_map = CreateStrongFunctionMap(empty, true); |
711 native_context()->set_strong_constructor_map(*strong_constructor_map); | 704 native_context()->set_strong_constructor_map(*strong_constructor_map); |
712 } | 705 } |
713 | 706 |
714 | 707 |
715 static void SetAccessors(Handle<Map> map, | |
716 Handle<String> name, | |
717 Handle<JSFunction> func) { | |
718 DescriptorArray* descs = map->instance_descriptors(); | |
719 int number = descs->SearchWithCache(*name, *map); | |
720 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); | |
721 accessors->set_getter(*func); | |
722 accessors->set_setter(*func); | |
723 } | |
724 | |
725 | |
726 static void ReplaceAccessors(Handle<Map> map, | 708 static void ReplaceAccessors(Handle<Map> map, |
727 Handle<String> name, | 709 Handle<String> name, |
728 PropertyAttributes attributes, | 710 PropertyAttributes attributes, |
729 Handle<AccessorPair> accessor_pair) { | 711 Handle<AccessorPair> accessor_pair) { |
730 DescriptorArray* descriptors = map->instance_descriptors(); | 712 DescriptorArray* descriptors = map->instance_descriptors(); |
731 int idx = descriptors->SearchWithCache(*name, *map); | 713 int idx = descriptors->SearchWithCache(*name, *map); |
732 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes); | 714 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes); |
733 descriptors->Replace(idx, &descriptor); | 715 descriptors->Replace(idx, &descriptor); |
734 } | 716 } |
735 | 717 |
736 | 718 |
737 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { | 719 void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) { |
738 SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction()); | 720 PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM); |
739 SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction()); | 721 Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower(); |
| 722 Handle<AccessorPair> accessors = factory()->NewAccessorPair(); |
| 723 accessors->set_getter(*thrower); |
| 724 accessors->set_setter(*thrower); |
| 725 |
| 726 ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors); |
| 727 ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors); |
740 } | 728 } |
741 | 729 |
742 | 730 |
743 static void AddToWeakNativeContextList(Context* context) { | 731 static void AddToWeakNativeContextList(Context* context) { |
744 DCHECK(context->IsNativeContext()); | 732 DCHECK(context->IsNativeContext()); |
745 Heap* heap = context->GetIsolate()->heap(); | 733 Heap* heap = context->GetIsolate()->heap(); |
746 #ifdef DEBUG | 734 #ifdef DEBUG |
747 { // NOLINT | 735 { // NOLINT |
748 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); | 736 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); |
749 // Check that context is not in the list yet. | 737 // Check that context is not in the list yet. |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 } | 1260 } |
1273 | 1261 |
1274 { // --- strict mode arguments map | 1262 { // --- strict mode arguments map |
1275 const PropertyAttributes attributes = | 1263 const PropertyAttributes attributes = |
1276 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 1264 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
1277 | 1265 |
1278 // Create the ThrowTypeError functions. | 1266 // Create the ThrowTypeError functions. |
1279 Handle<AccessorPair> callee = factory->NewAccessorPair(); | 1267 Handle<AccessorPair> callee = factory->NewAccessorPair(); |
1280 Handle<AccessorPair> caller = factory->NewAccessorPair(); | 1268 Handle<AccessorPair> caller = factory->NewAccessorPair(); |
1281 | 1269 |
1282 Handle<JSFunction> poison = GetStrictPoisonFunction(); | 1270 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction(); |
1283 | 1271 |
1284 // Install the ThrowTypeError functions. | 1272 // Install the ThrowTypeError functions. |
1285 callee->set_getter(*poison); | 1273 callee->set_getter(*poison); |
1286 callee->set_setter(*poison); | 1274 callee->set_setter(*poison); |
1287 caller->set_getter(*poison); | 1275 caller->set_getter(*poison); |
1288 caller->set_setter(*poison); | 1276 caller->set_setter(*poison); |
1289 | 1277 |
1290 // Create the map. Allocate one in-object field for length. | 1278 // Create the map. Allocate one in-object field for length. |
1291 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, | 1279 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, |
1292 Heap::kStrictArgumentsObjectSize); | 1280 Heap::kStrictArgumentsObjectSize); |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), | 2055 factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), |
2068 generator_function_prototype, | 2056 generator_function_prototype, |
2069 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); | 2057 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); |
2070 | 2058 |
2071 JSObject::AddProperty( | 2059 JSObject::AddProperty( |
2072 generator_function_prototype, | 2060 generator_function_prototype, |
2073 factory()->InternalizeUtf8String("prototype"), | 2061 factory()->InternalizeUtf8String("prototype"), |
2074 generator_object_prototype, | 2062 generator_object_prototype, |
2075 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 2063 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
2076 | 2064 |
| 2065 static const bool kUseStrictFunctionMap = true; |
2077 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, | 2066 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, |
2078 JSFunction::kSize, generator_function_prototype, | 2067 JSFunction::kSize, generator_function_prototype, |
2079 Builtins::kIllegal); | 2068 Builtins::kIllegal, kUseStrictFunctionMap); |
2080 | 2069 |
2081 // Create maps for generator functions and their prototypes. Store those | 2070 // Create maps for generator functions and their prototypes. Store those |
2082 // maps in the native context. | 2071 // maps in the native context. Generator functions do not have writable |
2083 Handle<Map> generator_function_map = | 2072 // prototypes, nor do they have "caller" or "arguments" accessors. |
2084 Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction"); | 2073 Handle<Map> strict_function_map(native_context()->strict_function_map()); |
2085 generator_function_map->SetPrototype(generator_function_prototype); | 2074 Handle<Map> sloppy_generator_function_map = |
| 2075 Map::Copy(strict_function_map, "SloppyGeneratorFunction"); |
| 2076 sloppy_generator_function_map->SetPrototype(generator_function_prototype); |
2086 native_context()->set_sloppy_generator_function_map( | 2077 native_context()->set_sloppy_generator_function_map( |
2087 *generator_function_map); | 2078 *sloppy_generator_function_map); |
2088 | 2079 |
2089 // The "arguments" and "caller" instance properties aren't specified, so | |
2090 // technically we could leave them out. They make even less sense for | |
2091 // generators than for functions. Still, the same argument that it makes | |
2092 // sense to keep them around but poisoned in strict mode applies to | |
2093 // generators as well. With poisoned accessors, naive callers can still | |
2094 // iterate over the properties without accessing them. | |
2095 // | |
2096 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs | |
2097 // in place, and the initial state of the generator function map shares the | |
2098 // accessor pair with sloppy functions. Also the error message should be | |
2099 // different. Also unhappily, we can't use the API accessors to implement | |
2100 // poisoning, because API accessors present themselves as data properties, | |
2101 // not accessor properties, and so getOwnPropertyDescriptor raises an | |
2102 // exception as it tries to get the values. Sadness. | |
2103 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); | |
2104 PropertyAttributes rw_attribs = | |
2105 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | |
2106 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); | |
2107 poison_pair->set_getter(*poison_function); | |
2108 poison_pair->set_setter(*poison_function); | |
2109 ReplaceAccessors(generator_function_map, factory()->arguments_string(), | |
2110 rw_attribs, poison_pair); | |
2111 ReplaceAccessors(generator_function_map, factory()->caller_string(), | |
2112 rw_attribs, poison_pair); | |
2113 | |
2114 Handle<Map> strict_function_map(native_context()->strict_function_map()); | |
2115 Handle<Map> strict_generator_function_map = | 2080 Handle<Map> strict_generator_function_map = |
2116 Map::Copy(strict_function_map, "StrictGeneratorFunction"); | 2081 Map::Copy(strict_function_map, "StrictGeneratorFunction"); |
2117 // "arguments" and "caller" already poisoned. | |
2118 strict_generator_function_map->SetPrototype(generator_function_prototype); | 2082 strict_generator_function_map->SetPrototype(generator_function_prototype); |
2119 native_context()->set_strict_generator_function_map( | 2083 native_context()->set_strict_generator_function_map( |
2120 *strict_generator_function_map); | 2084 *strict_generator_function_map); |
2121 | 2085 |
2122 Handle<Map> strong_function_map(native_context()->strong_function_map()); | 2086 Handle<Map> strong_function_map(native_context()->strong_function_map()); |
2123 Handle<Map> strong_generator_function_map = | 2087 Handle<Map> strong_generator_function_map = |
2124 Map::Copy(strong_function_map, "StrongGeneratorFunction"); | 2088 Map::Copy(strong_function_map, "StrongGeneratorFunction"); |
2125 strong_generator_function_map->SetPrototype(generator_function_prototype); | 2089 strong_generator_function_map->SetPrototype(generator_function_prototype); |
2126 native_context()->set_strong_generator_function_map( | 2090 native_context()->set_strong_generator_function_map( |
2127 *strong_generator_function_map); | 2091 *strong_generator_function_map); |
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2963 return from + sizeof(NestingCounterType); | 2927 return from + sizeof(NestingCounterType); |
2964 } | 2928 } |
2965 | 2929 |
2966 | 2930 |
2967 // Called when the top-level V8 mutex is destroyed. | 2931 // Called when the top-level V8 mutex is destroyed. |
2968 void Bootstrapper::FreeThreadResources() { | 2932 void Bootstrapper::FreeThreadResources() { |
2969 DCHECK(!IsActive()); | 2933 DCHECK(!IsActive()); |
2970 } | 2934 } |
2971 | 2935 |
2972 } } // namespace v8::internal | 2936 } } // namespace v8::internal |
OLD | NEW |