Chromium Code Reviews| 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 use_empty_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; |
|
rossberg
2015/03/26 15:06:45
Nit: I'm not superexcited about this change. When
caitp (gmail)
2015/03/26 15:09:46
I'm not keen on it either --- but changing it to a
| |
| 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, use_empty_function_map) | |
| 366 : factory->NewFunctionWithoutPrototype(internalized_name, call_code, | |
| 367 use_empty_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 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1271 } | 1259 } |
| 1272 | 1260 |
| 1273 { // --- strict mode arguments map | 1261 { // --- strict mode arguments map |
| 1274 const PropertyAttributes attributes = | 1262 const PropertyAttributes attributes = |
| 1275 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 1263 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 1276 | 1264 |
| 1277 // Create the ThrowTypeError functions. | 1265 // Create the ThrowTypeError functions. |
| 1278 Handle<AccessorPair> callee = factory->NewAccessorPair(); | 1266 Handle<AccessorPair> callee = factory->NewAccessorPair(); |
| 1279 Handle<AccessorPair> caller = factory->NewAccessorPair(); | 1267 Handle<AccessorPair> caller = factory->NewAccessorPair(); |
| 1280 | 1268 |
| 1281 Handle<JSFunction> poison = GetStrictPoisonFunction(); | 1269 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction(); |
| 1282 | 1270 |
| 1283 // Install the ThrowTypeError functions. | 1271 // Install the ThrowTypeError functions. |
| 1284 callee->set_getter(*poison); | 1272 callee->set_getter(*poison); |
| 1285 callee->set_setter(*poison); | 1273 callee->set_setter(*poison); |
| 1286 caller->set_getter(*poison); | 1274 caller->set_getter(*poison); |
| 1287 caller->set_setter(*poison); | 1275 caller->set_setter(*poison); |
| 1288 | 1276 |
| 1289 // Create the map. Allocate one in-object field for length. | 1277 // Create the map. Allocate one in-object field for length. |
| 1290 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, | 1278 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, |
| 1291 Heap::kStrictArgumentsObjectSize); | 1279 Heap::kStrictArgumentsObjectSize); |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2057 } | 2045 } |
| 2058 | 2046 |
| 2059 { | 2047 { |
| 2060 // Create generator meta-objects and install them on the builtins object. | 2048 // Create generator meta-objects and install them on the builtins object. |
| 2061 Handle<JSObject> builtins(native_context()->builtins()); | 2049 Handle<JSObject> builtins(native_context()->builtins()); |
| 2062 Handle<JSObject> generator_object_prototype = | 2050 Handle<JSObject> generator_object_prototype = |
| 2063 factory()->NewJSObject(isolate()->object_function(), TENURED); | 2051 factory()->NewJSObject(isolate()->object_function(), TENURED); |
| 2064 Handle<JSFunction> generator_function_prototype = | 2052 Handle<JSFunction> generator_function_prototype = |
| 2065 InstallFunction(builtins, "GeneratorFunctionPrototype", | 2053 InstallFunction(builtins, "GeneratorFunctionPrototype", |
| 2066 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, | 2054 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, |
| 2067 generator_object_prototype, Builtins::kIllegal); | 2055 generator_object_prototype, Builtins::kIllegal, true); |
| 2056 | |
| 2068 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, | 2057 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, |
| 2069 JSFunction::kSize, generator_function_prototype, | 2058 JSFunction::kSize, generator_function_prototype, |
| 2070 Builtins::kIllegal); | 2059 Builtins::kIllegal, true); |
| 2071 | 2060 |
| 2072 // Create maps for generator functions and their prototypes. Store those | 2061 // Create maps for generator functions and their prototypes. Store those |
| 2073 // maps in the native context. | 2062 // maps in the native context. |
| 2063 Handle<Map> strict_function_map(native_context()->strict_function_map()); | |
| 2074 Handle<Map> generator_function_map = | 2064 Handle<Map> generator_function_map = |
| 2075 Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction"); | |
| 2076 generator_function_map->SetPrototype(generator_function_prototype); | |
| 2077 native_context()->set_sloppy_generator_function_map( | |
| 2078 *generator_function_map); | |
| 2079 | |
| 2080 // The "arguments" and "caller" instance properties aren't specified, so | |
| 2081 // technically we could leave them out. They make even less sense for | |
| 2082 // generators than for functions. Still, the same argument that it makes | |
| 2083 // sense to keep them around but poisoned in strict mode applies to | |
| 2084 // generators as well. With poisoned accessors, naive callers can still | |
| 2085 // iterate over the properties without accessing them. | |
| 2086 // | |
| 2087 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs | |
| 2088 // in place, and the initial state of the generator function map shares the | |
| 2089 // accessor pair with sloppy functions. Also the error message should be | |
| 2090 // different. Also unhappily, we can't use the API accessors to implement | |
| 2091 // poisoning, because API accessors present themselves as data properties, | |
| 2092 // not accessor properties, and so getOwnPropertyDescriptor raises an | |
| 2093 // exception as it tries to get the values. Sadness. | |
| 2094 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); | |
| 2095 PropertyAttributes rw_attribs = | |
| 2096 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | |
| 2097 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); | |
| 2098 poison_pair->set_getter(*poison_function); | |
| 2099 poison_pair->set_setter(*poison_function); | |
| 2100 ReplaceAccessors(generator_function_map, factory()->arguments_string(), | |
| 2101 rw_attribs, poison_pair); | |
| 2102 ReplaceAccessors(generator_function_map, factory()->caller_string(), | |
| 2103 rw_attribs, poison_pair); | |
| 2104 | |
| 2105 Handle<Map> strict_function_map(native_context()->strict_function_map()); | |
| 2106 Handle<Map> strict_generator_function_map = | |
| 2107 Map::Copy(strict_function_map, "StrictGeneratorFunction"); | 2065 Map::Copy(strict_function_map, "StrictGeneratorFunction"); |
| 2108 // "arguments" and "caller" already poisoned. | 2066 // "arguments" and "caller" already poisoned. |
| 2109 strict_generator_function_map->SetPrototype(generator_function_prototype); | 2067 generator_function_map->SetPrototype(generator_function_prototype); |
| 2110 native_context()->set_strict_generator_function_map( | 2068 native_context()->set_generator_function_map(*generator_function_map); |
| 2111 *strict_generator_function_map); | |
| 2112 | 2069 |
| 2113 Handle<Map> strong_function_map(native_context()->strong_function_map()); | 2070 Handle<Map> strong_function_map(native_context()->strong_function_map()); |
| 2114 Handle<Map> strong_generator_function_map = | 2071 Handle<Map> strong_generator_function_map = |
| 2115 Map::Copy(strong_function_map, "StrongGeneratorFunction"); | 2072 Map::Copy(strong_function_map, "StrongGeneratorFunction"); |
| 2116 strong_generator_function_map->SetPrototype(generator_function_prototype); | 2073 strong_generator_function_map->SetPrototype(generator_function_prototype); |
| 2117 native_context()->set_strong_generator_function_map( | 2074 native_context()->set_strong_generator_function_map( |
| 2118 *strong_generator_function_map); | 2075 *strong_generator_function_map); |
| 2119 | 2076 |
| 2120 Handle<JSFunction> object_function(native_context()->object_function()); | 2077 Handle<JSFunction> object_function(native_context()->object_function()); |
| 2121 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0); | 2078 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0); |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2955 return from + sizeof(NestingCounterType); | 2912 return from + sizeof(NestingCounterType); |
| 2956 } | 2913 } |
| 2957 | 2914 |
| 2958 | 2915 |
| 2959 // Called when the top-level V8 mutex is destroyed. | 2916 // Called when the top-level V8 mutex is destroyed. |
| 2960 void Bootstrapper::FreeThreadResources() { | 2917 void Bootstrapper::FreeThreadResources() { |
| 2961 DCHECK(!IsActive()); | 2918 DCHECK(!IsActive()); |
| 2962 } | 2919 } |
| 2963 | 2920 |
| 2964 } } // namespace v8::internal | 2921 } } // namespace v8::internal |
| OLD | NEW |