Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: src/bootstrapper.cc

Issue 1027283004: [es6] do not add caller/arguments to ES6 function definitions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/builtins.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 } 1261 }
1274 1262
1275 { // --- strict mode arguments map 1263 { // --- strict mode arguments map
1276 const PropertyAttributes attributes = 1264 const PropertyAttributes attributes =
1277 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 1265 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1278 1266
1279 // Create the ThrowTypeError functions. 1267 // Create the ThrowTypeError functions.
1280 Handle<AccessorPair> callee = factory->NewAccessorPair(); 1268 Handle<AccessorPair> callee = factory->NewAccessorPair();
1281 Handle<AccessorPair> caller = factory->NewAccessorPair(); 1269 Handle<AccessorPair> caller = factory->NewAccessorPair();
1282 1270
1283 Handle<JSFunction> poison = GetStrictPoisonFunction(); 1271 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
1284 1272
1285 // Install the ThrowTypeError functions. 1273 // Install the ThrowTypeError functions.
1286 callee->set_getter(*poison); 1274 callee->set_getter(*poison);
1287 callee->set_setter(*poison); 1275 callee->set_setter(*poison);
1288 caller->set_getter(*poison); 1276 caller->set_getter(*poison);
1289 caller->set_setter(*poison); 1277 caller->set_setter(*poison);
1290 1278
1291 // Create the map. Allocate one in-object field for length. 1279 // Create the map. Allocate one in-object field for length.
1292 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, 1280 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1293 Heap::kStrictArgumentsObjectSize); 1281 Heap::kStrictArgumentsObjectSize);
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), 2058 factory()->InternalizeUtf8String("GeneratorFunctionPrototype"),
2071 generator_function_prototype, 2059 generator_function_prototype,
2072 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); 2060 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
2073 2061
2074 JSObject::AddProperty( 2062 JSObject::AddProperty(
2075 generator_function_prototype, 2063 generator_function_prototype,
2076 factory()->InternalizeUtf8String("prototype"), 2064 factory()->InternalizeUtf8String("prototype"),
2077 generator_object_prototype, 2065 generator_object_prototype,
2078 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); 2066 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2079 2067
2068 static const bool kUseStrictFunctionMap = true;
2080 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, 2069 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE,
2081 JSFunction::kSize, generator_function_prototype, 2070 JSFunction::kSize, generator_function_prototype,
2082 Builtins::kIllegal); 2071 Builtins::kIllegal, kUseStrictFunctionMap);
2083 2072
2084 // Create maps for generator functions and their prototypes. Store those 2073 // Create maps for generator functions and their prototypes. Store those
2085 // maps in the native context. 2074 // maps in the native context. Generator functions do not have writable
2086 Handle<Map> generator_function_map = 2075 // prototypes, nor do they have "caller" or "arguments" accessors.
2087 Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction"); 2076 Handle<Map> strict_function_map(native_context()->strict_function_map());
2088 generator_function_map->SetPrototype(generator_function_prototype); 2077 Handle<Map> sloppy_generator_function_map =
2078 Map::Copy(strict_function_map, "SloppyGeneratorFunction");
2079 sloppy_generator_function_map->SetPrototype(generator_function_prototype);
2089 native_context()->set_sloppy_generator_function_map( 2080 native_context()->set_sloppy_generator_function_map(
2090 *generator_function_map); 2081 *sloppy_generator_function_map);
2091 2082
2092 // The "arguments" and "caller" instance properties aren't specified, so
2093 // technically we could leave them out. They make even less sense for
2094 // generators than for functions. Still, the same argument that it makes
2095 // sense to keep them around but poisoned in strict mode applies to
2096 // generators as well. With poisoned accessors, naive callers can still
2097 // iterate over the properties without accessing them.
2098 //
2099 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs
2100 // in place, and the initial state of the generator function map shares the
2101 // accessor pair with sloppy functions. Also the error message should be
2102 // different. Also unhappily, we can't use the API accessors to implement
2103 // poisoning, because API accessors present themselves as data properties,
2104 // not accessor properties, and so getOwnPropertyDescriptor raises an
2105 // exception as it tries to get the values. Sadness.
2106 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair());
2107 PropertyAttributes rw_attribs =
2108 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2109 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction();
2110 poison_pair->set_getter(*poison_function);
2111 poison_pair->set_setter(*poison_function);
2112 ReplaceAccessors(generator_function_map, factory()->arguments_string(),
2113 rw_attribs, poison_pair);
2114 ReplaceAccessors(generator_function_map, factory()->caller_string(),
2115 rw_attribs, poison_pair);
2116
2117 Handle<Map> strict_function_map(native_context()->strict_function_map());
2118 Handle<Map> strict_generator_function_map = 2083 Handle<Map> strict_generator_function_map =
2119 Map::Copy(strict_function_map, "StrictGeneratorFunction"); 2084 Map::Copy(strict_function_map, "StrictGeneratorFunction");
2120 // "arguments" and "caller" already poisoned.
2121 strict_generator_function_map->SetPrototype(generator_function_prototype); 2085 strict_generator_function_map->SetPrototype(generator_function_prototype);
2122 native_context()->set_strict_generator_function_map( 2086 native_context()->set_strict_generator_function_map(
2123 *strict_generator_function_map); 2087 *strict_generator_function_map);
2124 2088
2125 Handle<Map> strong_function_map(native_context()->strong_function_map()); 2089 Handle<Map> strong_function_map(native_context()->strong_function_map());
2126 Handle<Map> strong_generator_function_map = 2090 Handle<Map> strong_generator_function_map =
2127 Map::Copy(strong_function_map, "StrongGeneratorFunction"); 2091 Map::Copy(strong_function_map, "StrongGeneratorFunction");
2128 strong_generator_function_map->SetPrototype(generator_function_prototype); 2092 strong_generator_function_map->SetPrototype(generator_function_prototype);
2129 native_context()->set_strong_generator_function_map( 2093 native_context()->set_strong_generator_function_map(
2130 *strong_generator_function_map); 2094 *strong_generator_function_map);
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 return from + sizeof(NestingCounterType); 2932 return from + sizeof(NestingCounterType);
2969 } 2933 }
2970 2934
2971 2935
2972 // Called when the top-level V8 mutex is destroyed. 2936 // Called when the top-level V8 mutex is destroyed.
2973 void Bootstrapper::FreeThreadResources() { 2937 void Bootstrapper::FreeThreadResources() {
2974 DCHECK(!IsActive()); 2938 DCHECK(!IsActive());
2975 } 2939 }
2976 2940
2977 } } // namespace v8::internal 2941 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/builtins.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698