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

Side by Side Diff: src/bootstrapper.cc

Issue 270133003: Poison .arguments and .caller for generator functions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/builtins.h » ('j') | test/mjsunit/harmony/generators-poisoned-properties.js » ('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 "bootstrapper.h" 5 #include "bootstrapper.h"
6 6
7 #include "accessors.h" 7 #include "accessors.h"
8 #include "isolate-inl.h" 8 #include "isolate-inl.h"
9 #include "natives.h" 9 #include "natives.h"
10 #include "snapshot.h" 10 #include "snapshot.h"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 private: 162 private:
163 Handle<Context> native_context() { return native_context_; } 163 Handle<Context> native_context() { return native_context_; }
164 164
165 // Creates some basic objects. Used for creating a context from scratch. 165 // Creates some basic objects. Used for creating a context from scratch.
166 void CreateRoots(); 166 void CreateRoots();
167 // Creates the empty function. Used for creating a context from scratch. 167 // Creates the empty function. Used for creating a context from scratch.
168 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); 168 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
169 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 169 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
170 Handle<JSFunction> GetThrowTypeErrorFunction(); 170 Handle<JSFunction> GetThrowTypeErrorFunction();
171 // Poison for sloppy generator function arguments/callee.
172 Handle<JSFunction> GetGeneratorFunctionPoison();
171 173
172 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); 174 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
173 175
174 // Make the "arguments" and "caller" properties throw a TypeError on access. 176 // Make the "arguments" and "caller" properties throw a TypeError on access.
175 void PoisonArgumentsAndCaller(Handle<Map> map); 177 void PoisonArgumentsAndCaller(Handle<Map> map);
176 178
177 // Creates the global objects using the global and the template passed in 179 // Creates the global objects using the global and the template passed in
178 // through the API. We call this regardless of whether we are building a 180 // through the API. We call this regardless of whether we are building a
179 // context from scratch or using a deserialized one from the partial snapshot 181 // context from scratch or using a deserialized one from the partial snapshot
180 // but in the latter case we don't use the objects it produces directly, as 182 // but in the latter case we don't use the objects it produces directly, as
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Isolate* isolate_; 297 Isolate* isolate_;
296 Handle<Context> result_; 298 Handle<Context> result_;
297 Handle<Context> native_context_; 299 Handle<Context> native_context_;
298 300
299 // Function maps. Function maps are created initially with a read only 301 // Function maps. Function maps are created initially with a read only
300 // prototype for the processing of JS builtins. Later the function maps are 302 // prototype for the processing of JS builtins. Later the function maps are
301 // replaced in order to make prototype writable. These are the final, writable 303 // replaced in order to make prototype writable. These are the final, writable
302 // prototype, maps. 304 // prototype, maps.
303 Handle<Map> sloppy_function_map_writable_prototype_; 305 Handle<Map> sloppy_function_map_writable_prototype_;
304 Handle<Map> strict_function_map_writable_prototype_; 306 Handle<Map> strict_function_map_writable_prototype_;
305 Handle<JSFunction> throw_type_error_function; 307 Handle<JSFunction> throw_type_error_function;
rossberg 2014/05/07 09:19:54 Nit: can we somehow rename this to make it more co
308 Handle<JSFunction> generator_function_poison;
306 309
307 BootstrapperActive active_; 310 BootstrapperActive active_;
308 friend class Bootstrapper; 311 friend class Bootstrapper;
309 }; 312 };
310 313
311 314
312 void Bootstrapper::Iterate(ObjectVisitor* v) { 315 void Bootstrapper::Iterate(ObjectVisitor* v) {
313 extensions_cache_.Iterate(v); 316 extensions_cache_.Iterate(v);
314 v->Synchronize(VisitorSynchronization::kExtensions); 317 v->Synchronize(VisitorSynchronization::kExtensions);
315 } 318 }
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 throw_type_error_function = factory()->NewFunction(name, code); 581 throw_type_error_function = factory()->NewFunction(name, code);
579 throw_type_error_function->set_map(native_context()->sloppy_function_map()); 582 throw_type_error_function->set_map(native_context()->sloppy_function_map());
580 throw_type_error_function->shared()->DontAdaptArguments(); 583 throw_type_error_function->shared()->DontAdaptArguments();
581 584
582 JSObject::PreventExtensions(throw_type_error_function).Assert(); 585 JSObject::PreventExtensions(throw_type_error_function).Assert();
583 } 586 }
584 return throw_type_error_function; 587 return throw_type_error_function;
585 } 588 }
586 589
587 590
591 Handle<JSFunction> Genesis::GetGeneratorFunctionPoison() {
592 if (generator_function_poison.is_null()) {
593 Handle<String> name = factory()->InternalizeOneByteString(
594 STATIC_ASCII_VECTOR("ThrowTypeError"));
595 Handle<Code> code(isolate()->builtins()->builtin(
596 Builtins::kGeneratorPoisonPill));
597 generator_function_poison = factory()->NewFunction(name, code);
598 generator_function_poison->set_map(native_context()->sloppy_function_map());
599 generator_function_poison->shared()->DontAdaptArguments();
600
601 JSObject::PreventExtensions(generator_function_poison).Assert();
602 }
603 return generator_function_poison;
604 }
605
606
588 Handle<Map> Genesis::CreateStrictFunctionMap( 607 Handle<Map> Genesis::CreateStrictFunctionMap(
589 PrototypePropertyMode prototype_mode, 608 PrototypePropertyMode prototype_mode,
590 Handle<JSFunction> empty_function) { 609 Handle<JSFunction> empty_function) {
591 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 610 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
592 SetStrictFunctionInstanceDescriptor(map, prototype_mode); 611 SetStrictFunctionInstanceDescriptor(map, prototype_mode);
593 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); 612 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
594 map->set_prototype(*empty_function); 613 map->set_prototype(*empty_function);
595 return map; 614 return map;
596 } 615 }
597 616
(...skipping 28 matching lines...) Expand all
626 Handle<String> name, 645 Handle<String> name,
627 Handle<JSFunction> func) { 646 Handle<JSFunction> func) {
628 DescriptorArray* descs = map->instance_descriptors(); 647 DescriptorArray* descs = map->instance_descriptors();
629 int number = descs->SearchWithCache(*name, *map); 648 int number = descs->SearchWithCache(*name, *map);
630 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); 649 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
631 accessors->set_getter(*func); 650 accessors->set_getter(*func);
632 accessors->set_setter(*func); 651 accessors->set_setter(*func);
633 } 652 }
634 653
635 654
655 static void ReplaceAccessors(Handle<Map> map,
656 Handle<String> name,
657 PropertyAttributes attributes,
658 Handle<AccessorPair> accessor_pair) {
659 DescriptorArray* descriptors = map->instance_descriptors();
660 int idx = descriptors->SearchWithCache(*name, *map);
661 CallbacksDescriptor descriptor(name, accessor_pair, attributes);
662 descriptors->Replace(idx, &descriptor);
663 }
664
665
636 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { 666 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
637 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction()); 667 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction());
638 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); 668 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction());
639 } 669 }
640 670
641 671
642 static void AddToWeakNativeContextList(Context* context) { 672 static void AddToWeakNativeContextList(Context* context) {
643 ASSERT(context->IsNativeContext()); 673 ASSERT(context->IsNativeContext());
644 Heap* heap = context->GetIsolate()->heap(); 674 Heap* heap = context->GetIsolate()->heap();
645 #ifdef DEBUG 675 #ifdef DEBUG
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, 1389 JS_FUNCTION_TYPE, JSFunction::kHeaderSize,
1360 generator_object_prototype, Builtins::kIllegal, 1390 generator_object_prototype, Builtins::kIllegal,
1361 false, false); 1391 false, false);
1362 InstallFunction(builtins, "GeneratorFunction", 1392 InstallFunction(builtins, "GeneratorFunction",
1363 JS_FUNCTION_TYPE, JSFunction::kSize, 1393 JS_FUNCTION_TYPE, JSFunction::kSize,
1364 generator_function_prototype, Builtins::kIllegal, 1394 generator_function_prototype, Builtins::kIllegal,
1365 false, false); 1395 false, false);
1366 1396
1367 // Create maps for generator functions and their prototypes. Store those 1397 // Create maps for generator functions and their prototypes. Store those
1368 // maps in the native context. 1398 // maps in the native context.
1369 Handle<Map> function_map(native_context()->sloppy_function_map()); 1399 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map());
1370 Handle<Map> generator_function_map = Map::Copy(function_map); 1400 Handle<Map> generator_function_map = Map::Copy(sloppy_function_map);
1371 generator_function_map->set_prototype(*generator_function_prototype); 1401 generator_function_map->set_prototype(*generator_function_prototype);
1372 native_context()->set_sloppy_generator_function_map( 1402 native_context()->set_sloppy_generator_function_map(
1373 *generator_function_map); 1403 *generator_function_map);
1374 1404
1375 Handle<Map> strict_mode_function_map( 1405 // The "arguments" and "caller" instance properties aren't specified, so
1376 native_context()->strict_function_map()); 1406 // technically we could leave them out. They make even less sense for
1407 // generators than for functions. Still, the same argument that it makes
1408 // sense to keep them around but poisoned in strict mode applies to
1409 // generators as well. With poisoned accessors, naive callers can still
1410 // iterate over the properties without accessing them.
1411 //
1412 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs
1413 // in place, and the initial state of the generator function map shares the
1414 // accessor pair with sloppy functions. Also the error message should be
1415 // different. Also unhappily, we can't use the API accessors to implement
1416 // poisoning, because API accessors present themselves as data properties,
1417 // not accessor properties, and so getOwnPropertyDescriptor raises an
1418 // exception as it tries to get the values. Sadness.
1419 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair());
1420 PropertyAttributes rw_attribs =
1421 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1422 poison_pair->set_getter(*GetGeneratorFunctionPoison());
1423 poison_pair->set_setter(*GetGeneratorFunctionPoison());
1424 ReplaceAccessors(generator_function_map, factory()->arguments_string(),
1425 rw_attribs, poison_pair);
1426 ReplaceAccessors(generator_function_map, factory()->caller_string(),
1427 rw_attribs, poison_pair);
1428
1429 Handle<Map> strict_function_map(native_context()->strict_function_map());
1377 Handle<Map> strict_mode_generator_function_map = 1430 Handle<Map> strict_mode_generator_function_map =
rossberg 2014/05/07 09:19:54 Nit: for consistency, drop _mode_ here, too.
1378 Map::Copy(strict_mode_function_map); 1431 Map::Copy(strict_function_map);
1432 // "arguments" and "caller" already poisoned.
1379 strict_mode_generator_function_map->set_prototype( 1433 strict_mode_generator_function_map->set_prototype(
1380 *generator_function_prototype); 1434 *generator_function_prototype);
1381 native_context()->set_strict_generator_function_map( 1435 native_context()->set_strict_generator_function_map(
1382 *strict_mode_generator_function_map); 1436 *strict_mode_generator_function_map);
1383 1437
1384 Handle<JSFunction> object_function(native_context()->object_function()); 1438 Handle<JSFunction> object_function(native_context()->object_function());
1385 Handle<Map> generator_object_prototype_map = Map::Create( 1439 Handle<Map> generator_object_prototype_map = Map::Create(
1386 object_function, 0); 1440 object_function, 0);
1387 generator_object_prototype_map->set_prototype( 1441 generator_object_prototype_map->set_prototype(
1388 *generator_object_prototype); 1442 *generator_object_prototype);
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 return from + sizeof(NestingCounterType); 2752 return from + sizeof(NestingCounterType);
2699 } 2753 }
2700 2754
2701 2755
2702 // Called when the top-level V8 mutex is destroyed. 2756 // Called when the top-level V8 mutex is destroyed.
2703 void Bootstrapper::FreeThreadResources() { 2757 void Bootstrapper::FreeThreadResources() {
2704 ASSERT(!IsActive()); 2758 ASSERT(!IsActive());
2705 } 2759 }
2706 2760
2707 } } // namespace v8::internal 2761 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/builtins.h » ('j') | test/mjsunit/harmony/generators-poisoned-properties.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698