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

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 + test262 exceptions 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') | src/builtins.cc » ('J')
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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/builtins.h » ('j') | src/builtins.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698