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

Side by Side Diff: src/objects.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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 | « src/objects.h ('k') | src/objects-debug.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 MaybeObject* maybe = GetHeap()->Uint32ToString(index); 512 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
513 if (!maybe->To<String>(&name)) return maybe; 513 if (!maybe->To<String>(&name)) return maybe;
514 return GetPropertyWithHandler(receiver, name); 514 return GetPropertyWithHandler(receiver, name);
515 } 515 }
516 516
517 517
518 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, 518 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
519 Handle<JSReceiver> receiver, 519 Handle<JSReceiver> receiver,
520 uint32_t index, 520 uint32_t index,
521 Handle<Object> value, 521 Handle<Object> value,
522 StrictModeFlag strict_mode) { 522 StrictMode strict_mode) {
523 Isolate* isolate = proxy->GetIsolate(); 523 Isolate* isolate = proxy->GetIsolate();
524 Handle<String> name = isolate->factory()->Uint32ToString(index); 524 Handle<String> name = isolate->factory()->Uint32ToString(index);
525 return SetPropertyWithHandler( 525 return SetPropertyWithHandler(
526 proxy, receiver, name, value, NONE, strict_mode); 526 proxy, receiver, name, value, NONE, strict_mode);
527 } 527 }
528 528
529 529
530 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { 530 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
531 Isolate* isolate = proxy->GetIsolate(); 531 Isolate* isolate = proxy->GetIsolate();
532 Handle<String> name = isolate->factory()->Uint32ToString(index); 532 Handle<String> name = isolate->factory()->Uint32ToString(index);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 608 }
609 break; 609 break;
610 } 610 }
611 default: 611 default:
612 UNREACHABLE(); 612 UNREACHABLE();
613 } 613 }
614 } 614 }
615 615
616 // No accessible property found. 616 // No accessible property found.
617 *attributes = ABSENT; 617 *attributes = ABSENT;
618 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_GET); 618 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_GET);
619 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 619 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
620 return isolate->factory()->undefined_value(); 620 return isolate->factory()->undefined_value();
621 } 621 }
622 622
623 623
624 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 624 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
625 Object* receiver, 625 Handle<JSObject> object,
626 LookupResult* result, 626 LookupResult* result,
627 Name* name, 627 Handle<Name> name,
628 bool continue_search) { 628 bool continue_search) {
629 if (result->IsProperty()) { 629 if (result->IsProperty()) {
630 switch (result->type()) { 630 switch (result->type()) {
631 case CALLBACKS: { 631 case CALLBACKS: {
632 // Only allow API accessors. 632 // Only allow API accessors.
633 Object* obj = result->GetCallbackObject(); 633 Handle<Object> obj(result->GetCallbackObject(), object->GetIsolate());
634 if (obj->IsAccessorInfo()) { 634 if (obj->IsAccessorInfo()) {
635 AccessorInfo* info = AccessorInfo::cast(obj); 635 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj);
636 if (info->all_can_read()) { 636 if (info->all_can_read()) {
637 return result->GetAttributes(); 637 return result->GetAttributes();
638 } 638 }
639 } else if (obj->IsAccessorPair()) { 639 } else if (obj->IsAccessorPair()) {
640 AccessorPair* pair = AccessorPair::cast(obj); 640 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(obj);
641 if (pair->all_can_read()) { 641 if (pair->all_can_read()) {
642 return result->GetAttributes(); 642 return result->GetAttributes();
643 } 643 }
644 } 644 }
645 break; 645 break;
646 } 646 }
647 647
648 case NORMAL: 648 case NORMAL:
649 case FIELD: 649 case FIELD:
650 case CONSTANT: { 650 case CONSTANT: {
651 if (!continue_search) break; 651 if (!continue_search) break;
652 // Search ALL_CAN_READ accessors in prototype chain. 652 // Search ALL_CAN_READ accessors in prototype chain.
653 LookupResult r(GetIsolate()); 653 LookupResult r(object->GetIsolate());
654 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 654 result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
655 if (r.IsProperty()) { 655 if (r.IsProperty()) {
656 return GetPropertyAttributeWithFailedAccessCheck(receiver, 656 return GetPropertyAttributeWithFailedAccessCheck(
657 &r, 657 object, &r, name, continue_search);
658 name,
659 continue_search);
660 } 658 }
661 break; 659 break;
662 } 660 }
663 661
664 case INTERCEPTOR: { 662 case INTERCEPTOR: {
665 // If the object has an interceptor, try real named properties. 663 // If the object has an interceptor, try real named properties.
666 // No access check in GetPropertyAttributeWithInterceptor. 664 // No access check in GetPropertyAttributeWithInterceptor.
667 LookupResult r(GetIsolate()); 665 LookupResult r(object->GetIsolate());
668 if (continue_search) { 666 if (continue_search) {
669 result->holder()->LookupRealNamedProperty(name, &r); 667 result->holder()->LookupRealNamedProperty(*name, &r);
670 } else { 668 } else {
671 result->holder()->LocalLookupRealNamedProperty(name, &r); 669 result->holder()->LocalLookupRealNamedProperty(*name, &r);
672 } 670 }
673 if (!r.IsFound()) break; 671 if (!r.IsFound()) break;
674 return GetPropertyAttributeWithFailedAccessCheck(receiver, 672 return GetPropertyAttributeWithFailedAccessCheck(
675 &r, 673 object, &r, name, continue_search);
676 name,
677 continue_search);
678 } 674 }
679 675
680 case HANDLER: 676 case HANDLER:
681 case TRANSITION: 677 case TRANSITION:
682 case NONEXISTENT: 678 case NONEXISTENT:
683 UNREACHABLE(); 679 UNREACHABLE();
684 } 680 }
685 } 681 }
686 682
687 GetIsolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 683 object->GetIsolate()->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
688 return ABSENT; 684 return ABSENT;
689 } 685 }
690 686
691 687
692 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { 688 Object* JSObject::GetNormalizedProperty(const LookupResult* result) {
693 ASSERT(!HasFastProperties()); 689 ASSERT(!HasFastProperties());
694 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 690 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
695 if (IsGlobalObject()) { 691 if (IsGlobalObject()) {
696 value = PropertyCell::cast(value)->value(); 692 value = PropertyCell::cast(value)->value();
697 } 693 }
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 return false; 1269 return false;
1274 } 1270 }
1275 bool is_ascii = this->IsOneByteRepresentation(); 1271 bool is_ascii = this->IsOneByteRepresentation();
1276 bool is_internalized = this->IsInternalizedString(); 1272 bool is_internalized = this->IsInternalizedString();
1277 1273
1278 // Morph the string to an external string by replacing the map and 1274 // Morph the string to an external string by replacing the map and
1279 // reinitializing the fields. This won't work if 1275 // reinitializing the fields. This won't work if
1280 // - the space the existing string occupies is too small for a regular 1276 // - the space the existing string occupies is too small for a regular
1281 // external string. 1277 // external string.
1282 // - the existing string is in old pointer space and the backing store of 1278 // - the existing string is in old pointer space and the backing store of
1283 // the external string is not aligned. The GC cannot deal with fields 1279 // the external string is not aligned. The GC cannot deal with a field
1284 // containing an unaligned address that points to outside of V8's heap. 1280 // containing a possibly unaligned address to outside of V8's heap.
1285 // In either case we resort to a short external string instead, omitting 1281 // In either case we resort to a short external string instead, omitting
1286 // the field caching the address of the backing store. When we encounter 1282 // the field caching the address of the backing store. When we encounter
1287 // short external strings in generated code, we need to bailout to runtime. 1283 // short external strings in generated code, we need to bailout to runtime.
1288 if (size < ExternalString::kSize || 1284 if (size < ExternalString::kSize ||
1289 (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) && 1285 heap->old_pointer_space()->Contains(this)) {
1290 heap->old_pointer_space()->Contains(this))) {
1291 this->set_map_no_write_barrier( 1286 this->set_map_no_write_barrier(
1292 is_internalized 1287 is_internalized
1293 ? (is_ascii 1288 ? (is_ascii
1294 ? heap-> 1289 ? heap->
1295 short_external_internalized_string_with_one_byte_data_map() 1290 short_external_internalized_string_with_one_byte_data_map()
1296 : heap->short_external_internalized_string_map()) 1291 : heap->short_external_internalized_string_map())
1297 : (is_ascii 1292 : (is_ascii
1298 ? heap->short_external_string_with_one_byte_data_map() 1293 ? heap->short_external_string_with_one_byte_data_map()
1299 : heap->short_external_string_map())); 1294 : heap->short_external_string_map()));
1300 } else { 1295 } else {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 if (size < ExternalString::kShortSize) { 1339 if (size < ExternalString::kShortSize) {
1345 return false; 1340 return false;
1346 } 1341 }
1347 bool is_internalized = this->IsInternalizedString(); 1342 bool is_internalized = this->IsInternalizedString();
1348 1343
1349 // Morph the string to an external string by replacing the map and 1344 // Morph the string to an external string by replacing the map and
1350 // reinitializing the fields. This won't work if 1345 // reinitializing the fields. This won't work if
1351 // - the space the existing string occupies is too small for a regular 1346 // - the space the existing string occupies is too small for a regular
1352 // external string. 1347 // external string.
1353 // - the existing string is in old pointer space and the backing store of 1348 // - the existing string is in old pointer space and the backing store of
1354 // the external string is not aligned. The GC cannot deal with fields 1349 // the external string is not aligned. The GC cannot deal with a field
1355 // containing an unaligned address that points to outside of V8's heap. 1350 // containing a possibly unaligned address to outside of V8's heap.
1356 // In either case we resort to a short external string instead, omitting 1351 // In either case we resort to a short external string instead, omitting
1357 // the field caching the address of the backing store. When we encounter 1352 // the field caching the address of the backing store. When we encounter
1358 // short external strings in generated code, we need to bailout to runtime. 1353 // short external strings in generated code, we need to bailout to runtime.
1359 if (size < ExternalString::kSize || 1354 if (size < ExternalString::kSize ||
1360 (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) && 1355 heap->old_pointer_space()->Contains(this)) {
1361 heap->old_pointer_space()->Contains(this))) {
1362 this->set_map_no_write_barrier( 1356 this->set_map_no_write_barrier(
1363 is_internalized ? heap->short_external_ascii_internalized_string_map() 1357 is_internalized ? heap->short_external_ascii_internalized_string_map()
1364 : heap->short_external_ascii_string_map()); 1358 : heap->short_external_ascii_string_map());
1365 } else { 1359 } else {
1366 this->set_map_no_write_barrier( 1360 this->set_map_no_write_barrier(
1367 is_internalized ? heap->external_ascii_internalized_string_map() 1361 is_internalized ? heap->external_ascii_internalized_string_map()
1368 : heap->external_ascii_string_map()); 1362 : heap->external_ascii_string_map());
1369 } 1363 }
1370 ExternalAsciiString* self = ExternalAsciiString::cast(this); 1364 ExternalAsciiString* self = ExternalAsciiString::cast(this);
1371 self->set_resource(resource); 1365 self->set_resource(resource);
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 static Handle<Object> NewStorageFor(Isolate* isolate, 1964 static Handle<Object> NewStorageFor(Isolate* isolate,
1971 Handle<Object> object, 1965 Handle<Object> object,
1972 Representation representation) { 1966 Representation representation) {
1973 Heap* heap = isolate->heap(); 1967 Heap* heap = isolate->heap();
1974 CALL_HEAP_FUNCTION(isolate, 1968 CALL_HEAP_FUNCTION(isolate,
1975 object->AllocateNewStorageFor(heap, representation), 1969 object->AllocateNewStorageFor(heap, representation),
1976 Object); 1970 Object);
1977 } 1971 }
1978 1972
1979 1973
1980 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
1981 Handle<Map> new_map,
1982 Handle<Name> name,
1983 Handle<Object> value,
1984 int field_index,
1985 Representation representation) {
1986 Isolate* isolate = object->GetIsolate();
1987
1988 // This method is used to transition to a field. If we are transitioning to a
1989 // double field, allocate new storage.
1990 Handle<Object> storage = NewStorageFor(isolate, value, representation);
1991
1992 if (object->map()->unused_property_fields() == 0) {
1993 int new_unused = new_map->unused_property_fields();
1994 Handle<FixedArray> properties(object->properties());
1995 Handle<FixedArray> values = isolate->factory()->CopySizeFixedArray(
1996 properties, properties->length() + new_unused + 1);
1997 object->set_properties(*values);
1998 }
1999
2000 object->set_map(*new_map);
2001 object->FastPropertyAtPut(field_index, *storage);
2002 }
2003
2004
2005 static MaybeObject* CopyAddFieldDescriptor(Map* map, 1974 static MaybeObject* CopyAddFieldDescriptor(Map* map,
2006 Name* name, 1975 Name* name,
2007 int index, 1976 int index,
2008 PropertyAttributes attributes, 1977 PropertyAttributes attributes,
2009 Representation representation, 1978 Representation representation,
2010 TransitionFlag flag) { 1979 TransitionFlag flag) {
2011 Map* new_map; 1980 Map* new_map;
2012 FieldDescriptor new_field_desc(name, index, attributes, representation); 1981 FieldDescriptor new_field_desc(name, index, attributes, representation);
2013 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); 1982 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
2014 if (!maybe_map->To(&new_map)) return maybe_map; 1983 if (!maybe_map->To(&new_map)) return maybe_map;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 2028
2060 // Compute the new index for new field. 2029 // Compute the new index for new field.
2061 int index = object->map()->NextFreePropertyIndex(); 2030 int index = object->map()->NextFreePropertyIndex();
2062 2031
2063 // Allocate new instance descriptors with (name, index) added 2032 // Allocate new instance descriptors with (name, index) added
2064 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 2033 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
2065 Representation representation = value->OptimalRepresentation(value_type); 2034 Representation representation = value->OptimalRepresentation(value_type);
2066 Handle<Map> new_map = CopyAddFieldDescriptor( 2035 Handle<Map> new_map = CopyAddFieldDescriptor(
2067 handle(object->map()), name, index, attributes, representation, flag); 2036 handle(object->map()), name, index, attributes, representation, flag);
2068 2037
2069 AddFastPropertyUsingMap(object, new_map, name, value, index, representation); 2038 JSObject::MigrateToMap(object, new_map);
2039
2040 if (representation.IsDouble()) {
2041 // Nothing more to be done.
2042 if (value->IsUninitialized()) return;
2043 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
2044 box->set_value(value->Number());
2045 } else {
2046 object->FastPropertyAtPut(index, *value);
2047 }
2070 } 2048 }
2071 2049
2072 2050
2073 static MaybeObject* CopyAddConstantDescriptor(Map* map, 2051 static MaybeObject* CopyAddConstantDescriptor(Map* map,
2074 Name* name, 2052 Name* name,
2075 Object* value, 2053 Object* value,
2076 PropertyAttributes attributes, 2054 PropertyAttributes attributes,
2077 TransitionFlag flag) { 2055 TransitionFlag flag) {
2078 ConstantDescriptor new_constant_desc(name, value, attributes); 2056 ConstantDescriptor new_constant_desc(name, value, attributes);
2079 return map->CopyAddDescriptor(&new_constant_desc, flag); 2057 return map->CopyAddDescriptor(&new_constant_desc, flag);
(...skipping 23 matching lines...) Expand all
2103 // Don't add transitions to special properties with non-trivial 2081 // Don't add transitions to special properties with non-trivial
2104 // attributes. 2082 // attributes.
2105 attributes != NONE) 2083 attributes != NONE)
2106 ? OMIT_TRANSITION 2084 ? OMIT_TRANSITION
2107 : initial_flag; 2085 : initial_flag;
2108 2086
2109 // Allocate new instance descriptors with (name, constant) added. 2087 // Allocate new instance descriptors with (name, constant) added.
2110 Handle<Map> new_map = CopyAddConstantDescriptor( 2088 Handle<Map> new_map = CopyAddConstantDescriptor(
2111 handle(object->map()), name, constant, attributes, flag); 2089 handle(object->map()), name, constant, attributes, flag);
2112 2090
2113 object->set_map(*new_map); 2091 JSObject::MigrateToMap(object, new_map);
2114 } 2092 }
2115 2093
2116 2094
2117 void JSObject::AddSlowProperty(Handle<JSObject> object, 2095 void JSObject::AddSlowProperty(Handle<JSObject> object,
2118 Handle<Name> name, 2096 Handle<Name> name,
2119 Handle<Object> value, 2097 Handle<Object> value,
2120 PropertyAttributes attributes) { 2098 PropertyAttributes attributes) {
2121 ASSERT(!object->HasFastProperties()); 2099 ASSERT(!object->HasFastProperties());
2122 Isolate* isolate = object->GetIsolate(); 2100 Isolate* isolate = object->GetIsolate();
2123 Handle<NameDictionary> dict(object->property_dictionary()); 2101 Handle<NameDictionary> dict(object->property_dictionary());
(...skipping 18 matching lines...) Expand all
2142 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 2120 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
2143 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); 2121 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
2144 if (*dict != *result) object->set_properties(*result); 2122 if (*dict != *result) object->set_properties(*result);
2145 } 2123 }
2146 2124
2147 2125
2148 Handle<Object> JSObject::AddProperty(Handle<JSObject> object, 2126 Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
2149 Handle<Name> name, 2127 Handle<Name> name,
2150 Handle<Object> value, 2128 Handle<Object> value,
2151 PropertyAttributes attributes, 2129 PropertyAttributes attributes,
2152 StrictModeFlag strict_mode, 2130 StrictMode strict_mode,
2153 JSReceiver::StoreFromKeyed store_mode, 2131 JSReceiver::StoreFromKeyed store_mode,
2154 ExtensibilityCheck extensibility_check, 2132 ExtensibilityCheck extensibility_check,
2155 ValueType value_type, 2133 ValueType value_type,
2156 StoreMode mode, 2134 StoreMode mode,
2157 TransitionFlag transition_flag) { 2135 TransitionFlag transition_flag) {
2158 ASSERT(!object->IsJSGlobalProxy()); 2136 ASSERT(!object->IsJSGlobalProxy());
2159 Isolate* isolate = object->GetIsolate(); 2137 Isolate* isolate = object->GetIsolate();
2160 2138
2161 if (!name->IsUniqueName()) { 2139 if (!name->IsUniqueName()) {
2162 name = isolate->factory()->InternalizeString( 2140 name = isolate->factory()->InternalizeString(
2163 Handle<String>::cast(name)); 2141 Handle<String>::cast(name));
2164 } 2142 }
2165 2143
2166 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && 2144 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2167 !object->map()->is_extensible()) { 2145 !object->map()->is_extensible()) {
2168 if (strict_mode == kNonStrictMode) { 2146 if (strict_mode == SLOPPY) {
2169 return value; 2147 return value;
2170 } else { 2148 } else {
2171 Handle<Object> args[1] = { name }; 2149 Handle<Object> args[1] = { name };
2172 Handle<Object> error = isolate->factory()->NewTypeError( 2150 Handle<Object> error = isolate->factory()->NewTypeError(
2173 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); 2151 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2174 isolate->Throw(*error); 2152 isolate->Throw(*error);
2175 return Handle<Object>(); 2153 return Handle<Object>();
2176 } 2154 }
2177 } 2155 }
2178 2156
(...skipping 13 matching lines...) Expand all
2192 } else { 2170 } else {
2193 // Normalize the object to prevent very large instance descriptors. 2171 // Normalize the object to prevent very large instance descriptors.
2194 // This eliminates unwanted N^2 allocation and lookup behavior. 2172 // This eliminates unwanted N^2 allocation and lookup behavior.
2195 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2173 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2196 AddSlowProperty(object, name, value, attributes); 2174 AddSlowProperty(object, name, value, attributes);
2197 } 2175 }
2198 } else { 2176 } else {
2199 AddSlowProperty(object, name, value, attributes); 2177 AddSlowProperty(object, name, value, attributes);
2200 } 2178 }
2201 2179
2202 if (FLAG_harmony_observation && 2180 if (object->map()->is_observed() &&
2203 object->map()->is_observed() &&
2204 *name != isolate->heap()->hidden_string()) { 2181 *name != isolate->heap()->hidden_string()) {
2205 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2182 Handle<Object> old_value = isolate->factory()->the_hole_value();
2206 EnqueueChangeRecord(object, "add", name, old_value); 2183 EnqueueChangeRecord(object, "add", name, old_value);
2207 } 2184 }
2208 2185
2209 return value; 2186 return value;
2210 } 2187 }
2211 2188
2212 2189
2213 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2190 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
(...skipping 17 matching lines...) Expand all
2231 &threw); 2208 &threw);
2232 ASSERT(!threw); 2209 ASSERT(!threw);
2233 } 2210 }
2234 2211
2235 2212
2236 Handle<Object> JSObject::SetPropertyPostInterceptor( 2213 Handle<Object> JSObject::SetPropertyPostInterceptor(
2237 Handle<JSObject> object, 2214 Handle<JSObject> object,
2238 Handle<Name> name, 2215 Handle<Name> name,
2239 Handle<Object> value, 2216 Handle<Object> value,
2240 PropertyAttributes attributes, 2217 PropertyAttributes attributes,
2241 StrictModeFlag strict_mode) { 2218 StrictMode strict_mode) {
2242 // Check local property, ignore interceptor. 2219 // Check local property, ignore interceptor.
2243 LookupResult result(object->GetIsolate()); 2220 LookupResult result(object->GetIsolate());
2244 object->LocalLookupRealNamedProperty(*name, &result); 2221 object->LocalLookupRealNamedProperty(*name, &result);
2245 if (!result.IsFound()) { 2222 if (!result.IsFound()) {
2246 object->map()->LookupTransition(*object, *name, &result); 2223 object->map()->LookupTransition(*object, *name, &result);
2247 } 2224 }
2248 if (result.IsFound()) { 2225 if (result.IsFound()) {
2249 // An existing property or a map transition was found. Use set property to 2226 // An existing property or a map transition was found. Use set property to
2250 // handle all these cases. 2227 // handle all these cases.
2251 return SetPropertyForResult(object, &result, name, value, attributes, 2228 return SetPropertyForResult(object, &result, name, value, attributes,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 2328
2352 bool Map::InstancesNeedRewriting(Map* target, 2329 bool Map::InstancesNeedRewriting(Map* target,
2353 int target_number_of_fields, 2330 int target_number_of_fields,
2354 int target_inobject, 2331 int target_inobject,
2355 int target_unused) { 2332 int target_unused) {
2356 // If fields were added (or removed), rewrite the instance. 2333 // If fields were added (or removed), rewrite the instance.
2357 int number_of_fields = NumberOfFields(); 2334 int number_of_fields = NumberOfFields();
2358 ASSERT(target_number_of_fields >= number_of_fields); 2335 ASSERT(target_number_of_fields >= number_of_fields);
2359 if (target_number_of_fields != number_of_fields) return true; 2336 if (target_number_of_fields != number_of_fields) return true;
2360 2337
2361 if (FLAG_track_double_fields) { 2338 // If smi descriptors were replaced by double descriptors, rewrite.
2362 // If smi descriptors were replaced by double descriptors, rewrite. 2339 DescriptorArray* old_desc = instance_descriptors();
2363 DescriptorArray* old_desc = instance_descriptors(); 2340 DescriptorArray* new_desc = target->instance_descriptors();
2364 DescriptorArray* new_desc = target->instance_descriptors(); 2341 int limit = NumberOfOwnDescriptors();
2365 int limit = NumberOfOwnDescriptors(); 2342 for (int i = 0; i < limit; i++) {
2366 for (int i = 0; i < limit; i++) { 2343 if (new_desc->GetDetails(i).representation().IsDouble() &&
2367 if (new_desc->GetDetails(i).representation().IsDouble() && 2344 !old_desc->GetDetails(i).representation().IsDouble()) {
2368 !old_desc->GetDetails(i).representation().IsDouble()) { 2345 return true;
2369 return true;
2370 }
2371 } 2346 }
2372 } 2347 }
2373 2348
2374 // If no fields were added, and no inobject properties were removed, setting 2349 // If no fields were added, and no inobject properties were removed, setting
2375 // the map is sufficient. 2350 // the map is sufficient.
2376 if (target_inobject == inobject_properties()) return false; 2351 if (target_inobject == inobject_properties()) return false;
2377 // In-object slack tracking may have reduced the object size of the new map. 2352 // In-object slack tracking may have reduced the object size of the new map.
2378 // In that case, succeed if all existing fields were inobject, and they still 2353 // In that case, succeed if all existing fields were inobject, and they still
2379 // fit within the new inobject size. 2354 // fit within the new inobject size.
2380 ASSERT(target_inobject < inobject_properties()); 2355 ASSERT(target_inobject < inobject_properties());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2416 object->set_map(*new_map); 2391 object->set_map(*new_map);
2417 return; 2392 return;
2418 } 2393 }
2419 2394
2420 int total_size = number_of_fields + unused; 2395 int total_size = number_of_fields + unused;
2421 int external = total_size - inobject; 2396 int external = total_size - inobject;
2422 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); 2397 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
2423 2398
2424 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); 2399 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2425 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); 2400 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
2426 int descriptors = new_map->NumberOfOwnDescriptors(); 2401 int old_nof = old_map->NumberOfOwnDescriptors();
2402 int new_nof = new_map->NumberOfOwnDescriptors();
2427 2403
2428 for (int i = 0; i < descriptors; i++) { 2404 // This method only supports generalizing instances to at least the same
2405 // number of properties.
2406 ASSERT(old_nof <= new_nof);
2407
2408 for (int i = 0; i < old_nof; i++) {
2429 PropertyDetails details = new_descriptors->GetDetails(i); 2409 PropertyDetails details = new_descriptors->GetDetails(i);
2430 if (details.type() != FIELD) continue; 2410 if (details.type() != FIELD) continue;
2431 PropertyDetails old_details = old_descriptors->GetDetails(i); 2411 PropertyDetails old_details = old_descriptors->GetDetails(i);
2432 if (old_details.type() == CALLBACKS) { 2412 if (old_details.type() == CALLBACKS) {
2433 ASSERT(details.representation().IsTagged()); 2413 ASSERT(details.representation().IsTagged());
2434 continue; 2414 continue;
2435 } 2415 }
2436 ASSERT(old_details.type() == CONSTANT || 2416 ASSERT(old_details.type() == CONSTANT ||
2437 old_details.type() == FIELD); 2417 old_details.type() == FIELD);
2438 Object* raw_value = old_details.type() == CONSTANT 2418 Object* raw_value = old_details.type() == CONSTANT
2439 ? old_descriptors->GetValue(i) 2419 ? old_descriptors->GetValue(i)
2440 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2420 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2441 Handle<Object> value(raw_value, isolate); 2421 Handle<Object> value(raw_value, isolate);
2442 if (FLAG_track_double_fields && 2422 if (!old_details.representation().IsDouble() &&
2443 !old_details.representation().IsDouble() &&
2444 details.representation().IsDouble()) { 2423 details.representation().IsDouble()) {
2445 if (old_details.representation().IsNone()) { 2424 if (old_details.representation().IsNone()) {
2446 value = handle(Smi::FromInt(0), isolate); 2425 value = handle(Smi::FromInt(0), isolate);
2447 } 2426 }
2448 value = NewStorageFor(isolate, value, details.representation()); 2427 value = NewStorageFor(isolate, value, details.representation());
2449 } 2428 }
2450 ASSERT(!(FLAG_track_double_fields && 2429 ASSERT(!(details.representation().IsDouble() && value->IsSmi()));
2451 details.representation().IsDouble() &&
2452 value->IsSmi()));
2453 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2430 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2454 if (target_index < 0) target_index += total_size; 2431 if (target_index < 0) target_index += total_size;
2455 array->set(target_index, *value); 2432 array->set(target_index, *value);
2456 } 2433 }
2457 2434
2435 for (int i = old_nof; i < new_nof; i++) {
2436 PropertyDetails details = new_descriptors->GetDetails(i);
2437 if (details.type() != FIELD) continue;
2438 if (details.representation().IsDouble()) {
2439 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2440 if (target_index < 0) target_index += total_size;
2441 Handle<Object> box = isolate->factory()->NewHeapNumber(0);
2442 array->set(target_index, *box);
2443 }
2444 }
2445
2458 // From here on we cannot fail and we shouldn't GC anymore. 2446 // From here on we cannot fail and we shouldn't GC anymore.
2459 DisallowHeapAllocation no_allocation; 2447 DisallowHeapAllocation no_allocation;
2460 2448
2461 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2449 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2462 // avoid overwriting |one_pointer_filler_map|. 2450 // avoid overwriting |one_pointer_filler_map|.
2463 int limit = Min(inobject, number_of_fields); 2451 int limit = Min(inobject, number_of_fields);
2464 for (int i = 0; i < limit; i++) { 2452 for (int i = 0; i < limit; i++) {
2465 object->FastPropertyAtPut(i, array->get(external + i)); 2453 object->FastPropertyAtPut(i, array->get(external + i));
2466 } 2454 }
2467 2455
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 new_map->NumberOfOwnDescriptors(), 2533 new_map->NumberOfOwnDescriptors(),
2546 new_map->NumberOfOwnDescriptors(), 2534 new_map->NumberOfOwnDescriptors(),
2547 details.type() == CONSTANT && store_mode == FORCE_FIELD, 2535 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2548 Representation::Tagged(), Representation::Tagged()); 2536 Representation::Tagged(), Representation::Tagged());
2549 } 2537 }
2550 return new_map; 2538 return new_map;
2551 } 2539 }
2552 2540
2553 2541
2554 void Map::DeprecateTransitionTree() { 2542 void Map::DeprecateTransitionTree() {
2555 if (!FLAG_track_fields) return;
2556 if (is_deprecated()) return; 2543 if (is_deprecated()) return;
2557 if (HasTransitionArray()) { 2544 if (HasTransitionArray()) {
2558 TransitionArray* transitions = this->transitions(); 2545 TransitionArray* transitions = this->transitions();
2559 for (int i = 0; i < transitions->number_of_transitions(); i++) { 2546 for (int i = 0; i < transitions->number_of_transitions(); i++) {
2560 transitions->GetTarget(i)->DeprecateTransitionTree(); 2547 transitions->GetTarget(i)->DeprecateTransitionTree();
2561 } 2548 }
2562 } 2549 }
2563 deprecate(); 2550 deprecate();
2564 dependent_code()->DeoptimizeDependentCodeGroup( 2551 dependent_code()->DeoptimizeDependentCodeGroup(
2565 GetIsolate(), DependentCode::kTransitionGroup); 2552 GetIsolate(), DependentCode::kTransitionGroup);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 PropertyDetails details = descriptors->GetDetails(i); 2613 PropertyDetails details = descriptors->GetDetails(i);
2627 PropertyDetails target_details = 2614 PropertyDetails target_details =
2628 current->instance_descriptors()->GetDetails(i); 2615 current->instance_descriptors()->GetDetails(i);
2629 if (details.attributes() != target_details.attributes()) return NULL; 2616 if (details.attributes() != target_details.attributes()) return NULL;
2630 if (details.type() == CALLBACKS) { 2617 if (details.type() == CALLBACKS) {
2631 if (target_details.type() != CALLBACKS) return NULL; 2618 if (target_details.type() != CALLBACKS) return NULL;
2632 if (descriptors->GetValue(i) != 2619 if (descriptors->GetValue(i) !=
2633 current->instance_descriptors()->GetValue(i)) { 2620 current->instance_descriptors()->GetValue(i)) {
2634 return NULL; 2621 return NULL;
2635 } 2622 }
2623 } else if (target_details.type() == CALLBACKS) {
2624 return NULL;
2636 } 2625 }
2637 } 2626 }
2638 2627
2639 return current; 2628 return current;
2640 } 2629 }
2641 2630
2642 2631
2643 Map* Map::FindLastMatchMap(int verbatim, 2632 Map* Map::FindLastMatchMap(int verbatim,
2644 int length, 2633 int length,
2645 DescriptorArray* descriptors) { 2634 DescriptorArray* descriptors) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2847 2836
2848 return handle(updated); 2837 return handle(updated);
2849 } 2838 }
2850 2839
2851 2840
2852 Handle<Object> JSObject::SetPropertyWithInterceptor( 2841 Handle<Object> JSObject::SetPropertyWithInterceptor(
2853 Handle<JSObject> object, 2842 Handle<JSObject> object,
2854 Handle<Name> name, 2843 Handle<Name> name,
2855 Handle<Object> value, 2844 Handle<Object> value,
2856 PropertyAttributes attributes, 2845 PropertyAttributes attributes,
2857 StrictModeFlag strict_mode) { 2846 StrictMode strict_mode) {
2858 // TODO(rossberg): Support symbols in the API. 2847 // TODO(rossberg): Support symbols in the API.
2859 if (name->IsSymbol()) return value; 2848 if (name->IsSymbol()) return value;
2860 Isolate* isolate = object->GetIsolate(); 2849 Isolate* isolate = object->GetIsolate();
2861 Handle<String> name_string = Handle<String>::cast(name); 2850 Handle<String> name_string = Handle<String>::cast(name);
2862 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); 2851 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
2863 if (!interceptor->setter()->IsUndefined()) { 2852 if (!interceptor->setter()->IsUndefined()) {
2864 LOG(isolate, 2853 LOG(isolate,
2865 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); 2854 ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
2866 PropertyCallbackArguments args( 2855 PropertyCallbackArguments args(
2867 isolate, interceptor->data(), *object, *object); 2856 isolate, interceptor->data(), *object, *object);
(...skipping 11 matching lines...) Expand all
2879 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); 2868 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
2880 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 2869 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2881 return result; 2870 return result;
2882 } 2871 }
2883 2872
2884 2873
2885 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 2874 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2886 Handle<Name> name, 2875 Handle<Name> name,
2887 Handle<Object> value, 2876 Handle<Object> value,
2888 PropertyAttributes attributes, 2877 PropertyAttributes attributes,
2889 StrictModeFlag strict_mode, 2878 StrictMode strict_mode,
2890 StoreFromKeyed store_mode) { 2879 StoreFromKeyed store_mode) {
2891 LookupResult result(object->GetIsolate()); 2880 LookupResult result(object->GetIsolate());
2892 object->LocalLookup(*name, &result, true); 2881 object->LocalLookup(*name, &result, true);
2893 if (!result.IsFound()) { 2882 if (!result.IsFound()) {
2894 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); 2883 object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2895 } 2884 }
2896 return SetProperty(object, &result, name, value, attributes, strict_mode, 2885 return SetProperty(object, &result, name, value, attributes, strict_mode,
2897 store_mode); 2886 store_mode);
2898 } 2887 }
2899 2888
2900 2889
2901 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object, 2890 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
2902 Handle<Object> structure, 2891 Handle<Object> structure,
2903 Handle<Name> name, 2892 Handle<Name> name,
2904 Handle<Object> value, 2893 Handle<Object> value,
2905 Handle<JSObject> holder, 2894 Handle<JSObject> holder,
2906 StrictModeFlag strict_mode) { 2895 StrictMode strict_mode) {
2907 Isolate* isolate = object->GetIsolate(); 2896 Isolate* isolate = object->GetIsolate();
2908 2897
2909 // We should never get here to initialize a const with the hole 2898 // We should never get here to initialize a const with the hole
2910 // value since a const declaration would conflict with the setter. 2899 // value since a const declaration would conflict with the setter.
2911 ASSERT(!value->IsTheHole()); 2900 ASSERT(!value->IsTheHole());
2912 2901
2913 // To accommodate both the old and the new api we switch on the 2902 // To accommodate both the old and the new api we switch on the
2914 // data structure used to store the callbacks. Eventually foreign 2903 // data structure used to store the callbacks. Eventually foreign
2915 // callbacks should be phased out. 2904 // callbacks should be phased out.
2916 if (structure->IsForeign()) { 2905 if (structure->IsForeign()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 return value; 2944 return value;
2956 } 2945 }
2957 2946
2958 if (structure->IsAccessorPair()) { 2947 if (structure->IsAccessorPair()) {
2959 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 2948 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
2960 if (setter->IsSpecFunction()) { 2949 if (setter->IsSpecFunction()) {
2961 // TODO(rossberg): nicer would be to cast to some JSCallable here... 2950 // TODO(rossberg): nicer would be to cast to some JSCallable here...
2962 return SetPropertyWithDefinedSetter( 2951 return SetPropertyWithDefinedSetter(
2963 object, Handle<JSReceiver>::cast(setter), value); 2952 object, Handle<JSReceiver>::cast(setter), value);
2964 } else { 2953 } else {
2965 if (strict_mode == kNonStrictMode) { 2954 if (strict_mode == SLOPPY) return value;
2966 return value;
2967 }
2968 Handle<Object> args[2] = { name, holder }; 2955 Handle<Object> args[2] = { name, holder };
2969 Handle<Object> error = 2956 Handle<Object> error =
2970 isolate->factory()->NewTypeError("no_setter_in_callback", 2957 isolate->factory()->NewTypeError("no_setter_in_callback",
2971 HandleVector(args, 2)); 2958 HandleVector(args, 2));
2972 isolate->Throw(*error); 2959 isolate->Throw(*error);
2973 return Handle<Object>(); 2960 return Handle<Object>();
2974 } 2961 }
2975 } 2962 }
2976 2963
2977 // TODO(dcarney): Handle correctly. 2964 // TODO(dcarney): Handle correctly.
(...skipping 30 matching lines...) Expand all
3008 if (has_pending_exception) return Handle<Object>(); 2995 if (has_pending_exception) return Handle<Object>();
3009 return value; 2996 return value;
3010 } 2997 }
3011 2998
3012 2999
3013 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( 3000 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
3014 Handle<JSObject> object, 3001 Handle<JSObject> object,
3015 uint32_t index, 3002 uint32_t index,
3016 Handle<Object> value, 3003 Handle<Object> value,
3017 bool* found, 3004 bool* found,
3018 StrictModeFlag strict_mode) { 3005 StrictMode strict_mode) {
3019 Isolate *isolate = object->GetIsolate(); 3006 Isolate *isolate = object->GetIsolate();
3020 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); 3007 for (Handle<Object> proto = handle(object->GetPrototype(), isolate);
3021 !proto->IsNull(); 3008 !proto->IsNull();
3022 proto = handle(proto->GetPrototype(isolate), isolate)) { 3009 proto = handle(proto->GetPrototype(isolate), isolate)) {
3023 if (proto->IsJSProxy()) { 3010 if (proto->IsJSProxy()) {
3024 return JSProxy::SetPropertyViaPrototypesWithHandler( 3011 return JSProxy::SetPropertyViaPrototypesWithHandler(
3025 Handle<JSProxy>::cast(proto), 3012 Handle<JSProxy>::cast(proto),
3026 object, 3013 object,
3027 isolate->factory()->Uint32ToString(index), // name 3014 isolate->factory()->Uint32ToString(index), // name
3028 value, 3015 value,
(...skipping 19 matching lines...) Expand all
3048 } 3035 }
3049 *found = false; 3036 *found = false;
3050 return isolate->factory()->the_hole_value(); 3037 return isolate->factory()->the_hole_value();
3051 } 3038 }
3052 3039
3053 3040
3054 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, 3041 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
3055 Handle<Name> name, 3042 Handle<Name> name,
3056 Handle<Object> value, 3043 Handle<Object> value,
3057 PropertyAttributes attributes, 3044 PropertyAttributes attributes,
3058 StrictModeFlag strict_mode, 3045 StrictMode strict_mode,
3059 bool* done) { 3046 bool* done) {
3060 Isolate* isolate = object->GetIsolate(); 3047 Isolate* isolate = object->GetIsolate();
3061 3048
3062 *done = false; 3049 *done = false;
3063 // We could not find a local property so let's check whether there is an 3050 // We could not find a local property so let's check whether there is an
3064 // accessor that wants to handle the property, or whether the property is 3051 // accessor that wants to handle the property, or whether the property is
3065 // read-only on the prototype chain. 3052 // read-only on the prototype chain.
3066 LookupResult result(isolate); 3053 LookupResult result(isolate);
3067 object->LookupRealNamedPropertyInPrototypes(*name, &result); 3054 object->LookupRealNamedPropertyInPrototypes(*name, &result);
3068 if (result.IsFound()) { 3055 if (result.IsFound()) {
3069 switch (result.type()) { 3056 switch (result.type()) {
3070 case NORMAL: 3057 case NORMAL:
3071 case FIELD: 3058 case FIELD:
3072 case CONSTANT: 3059 case CONSTANT:
3073 *done = result.IsReadOnly(); 3060 *done = result.IsReadOnly();
3074 break; 3061 break;
3075 case INTERCEPTOR: { 3062 case INTERCEPTOR: {
3076 PropertyAttributes attr = 3063 PropertyAttributes attr = GetPropertyAttributeWithInterceptor(
3077 result.holder()->GetPropertyAttributeWithInterceptor( 3064 handle(result.holder()), object, name, true);
3078 *object, *name, true);
3079 *done = !!(attr & READ_ONLY); 3065 *done = !!(attr & READ_ONLY);
3080 break; 3066 break;
3081 } 3067 }
3082 case CALLBACKS: { 3068 case CALLBACKS: {
3083 if (!FLAG_es5_readonly && result.IsReadOnly()) break;
3084 *done = true; 3069 *done = true;
3085 Handle<Object> callback_object(result.GetCallbackObject(), isolate); 3070 Handle<Object> callback_object(result.GetCallbackObject(), isolate);
3086 return SetPropertyWithCallback(object, callback_object, name, value, 3071 return SetPropertyWithCallback(object, callback_object, name, value,
3087 handle(result.holder()), strict_mode); 3072 handle(result.holder()), strict_mode);
3088 } 3073 }
3089 case HANDLER: { 3074 case HANDLER: {
3090 Handle<JSProxy> proxy(result.proxy()); 3075 Handle<JSProxy> proxy(result.proxy());
3091 return JSProxy::SetPropertyViaPrototypesWithHandler( 3076 return JSProxy::SetPropertyViaPrototypesWithHandler(
3092 proxy, object, name, value, attributes, strict_mode, done); 3077 proxy, object, name, value, attributes, strict_mode, done);
3093 } 3078 }
3094 case TRANSITION: 3079 case TRANSITION:
3095 case NONEXISTENT: 3080 case NONEXISTENT:
3096 UNREACHABLE(); 3081 UNREACHABLE();
3097 break; 3082 break;
3098 } 3083 }
3099 } 3084 }
3100 3085
3101 // If we get here with *done true, we have encountered a read-only property. 3086 // If we get here with *done true, we have encountered a read-only property.
3102 if (!FLAG_es5_readonly) *done = false;
3103 if (*done) { 3087 if (*done) {
3104 if (strict_mode == kNonStrictMode) return value; 3088 if (strict_mode == SLOPPY) return value;
3105 Handle<Object> args[] = { name, object }; 3089 Handle<Object> args[] = { name, object };
3106 Handle<Object> error = isolate->factory()->NewTypeError( 3090 Handle<Object> error = isolate->factory()->NewTypeError(
3107 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 3091 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3108 isolate->Throw(*error); 3092 isolate->Throw(*error);
3109 return Handle<Object>(); 3093 return Handle<Object>();
3110 } 3094 }
3111 return isolate->factory()->the_hole_value(); 3095 return isolate->factory()->the_hole_value();
3112 } 3096 }
3113 3097
3114 3098
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
3383 3367
3384 if (closest_map->elements_kind() == kind) { 3368 if (closest_map->elements_kind() == kind) {
3385 return closest_map; 3369 return closest_map;
3386 } 3370 }
3387 3371
3388 return AddMissingElementsTransitions(closest_map, kind); 3372 return AddMissingElementsTransitions(closest_map, kind);
3389 } 3373 }
3390 3374
3391 3375
3392 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { 3376 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
3377 DisallowHeapAllocation no_gc;
3393 if (IsJSGlobalProxy()) { 3378 if (IsJSGlobalProxy()) {
3394 Object* proto = GetPrototype(); 3379 Object* proto = GetPrototype();
3395 if (proto->IsNull()) return result->NotFound(); 3380 if (proto->IsNull()) return result->NotFound();
3396 ASSERT(proto->IsJSGlobalObject()); 3381 ASSERT(proto->IsJSGlobalObject());
3397 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); 3382 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result);
3398 } 3383 }
3399 3384
3400 if (HasFastProperties()) { 3385 if (HasFastProperties()) {
3401 map()->LookupDescriptor(this, name, result); 3386 map()->LookupDescriptor(this, name, result);
3402 // A property or a map transition was found. We return all of these result 3387 // A property or a map transition was found. We return all of these result
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3462 } 3447 }
3463 3448
3464 3449
3465 // We only need to deal with CALLBACKS and INTERCEPTORS 3450 // We only need to deal with CALLBACKS and INTERCEPTORS
3466 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck( 3451 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
3467 Handle<JSObject> object, 3452 Handle<JSObject> object,
3468 LookupResult* result, 3453 LookupResult* result,
3469 Handle<Name> name, 3454 Handle<Name> name,
3470 Handle<Object> value, 3455 Handle<Object> value,
3471 bool check_prototype, 3456 bool check_prototype,
3472 StrictModeFlag strict_mode) { 3457 StrictMode strict_mode) {
3473 if (check_prototype && !result->IsProperty()) { 3458 if (check_prototype && !result->IsProperty()) {
3474 object->LookupRealNamedPropertyInPrototypes(*name, result); 3459 object->LookupRealNamedPropertyInPrototypes(*name, result);
3475 } 3460 }
3476 3461
3477 if (result->IsProperty()) { 3462 if (result->IsProperty()) {
3478 if (!result->IsReadOnly()) { 3463 if (!result->IsReadOnly()) {
3479 switch (result->type()) { 3464 switch (result->type()) {
3480 case CALLBACKS: { 3465 case CALLBACKS: {
3481 Object* obj = result->GetCallbackObject(); 3466 Object* obj = result->GetCallbackObject();
3482 if (obj->IsAccessorInfo()) { 3467 if (obj->IsAccessorInfo()) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3518 break; 3503 break;
3519 } 3504 }
3520 default: { 3505 default: {
3521 break; 3506 break;
3522 } 3507 }
3523 } 3508 }
3524 } 3509 }
3525 } 3510 }
3526 3511
3527 Isolate* isolate = object->GetIsolate(); 3512 Isolate* isolate = object->GetIsolate();
3528 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); 3513 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
3529 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 3514 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
3530 return value; 3515 return value;
3531 } 3516 }
3532 3517
3533 3518
3534 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 3519 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3535 LookupResult* result, 3520 LookupResult* result,
3536 Handle<Name> key, 3521 Handle<Name> key,
3537 Handle<Object> value, 3522 Handle<Object> value,
3538 PropertyAttributes attributes, 3523 PropertyAttributes attributes,
3539 StrictModeFlag strict_mode, 3524 StrictMode strict_mode,
3540 StoreFromKeyed store_mode) { 3525 StoreFromKeyed store_mode) {
3541 if (result->IsHandler()) { 3526 if (result->IsHandler()) {
3542 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), 3527 return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
3543 object, key, value, attributes, strict_mode); 3528 object, key, value, attributes, strict_mode);
3544 } else { 3529 } else {
3545 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), 3530 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object),
3546 result, key, value, attributes, strict_mode, store_mode); 3531 result, key, value, attributes, strict_mode, store_mode);
3547 } 3532 }
3548 } 3533 }
3549 3534
(...skipping 11 matching lines...) Expand all
3561 3546
3562 return result->BooleanValue(); 3547 return result->BooleanValue();
3563 } 3548 }
3564 3549
3565 3550
3566 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, 3551 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
3567 Handle<JSReceiver> receiver, 3552 Handle<JSReceiver> receiver,
3568 Handle<Name> name, 3553 Handle<Name> name,
3569 Handle<Object> value, 3554 Handle<Object> value,
3570 PropertyAttributes attributes, 3555 PropertyAttributes attributes,
3571 StrictModeFlag strict_mode) { 3556 StrictMode strict_mode) {
3572 Isolate* isolate = proxy->GetIsolate(); 3557 Isolate* isolate = proxy->GetIsolate();
3573 3558
3574 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3559 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3575 if (name->IsSymbol()) return value; 3560 if (name->IsSymbol()) return value;
3576 3561
3577 Handle<Object> args[] = { receiver, name, value }; 3562 Handle<Object> args[] = { receiver, name, value };
3578 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 3563 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
3579 if (isolate->has_pending_exception()) return Handle<Object>(); 3564 if (isolate->has_pending_exception()) return Handle<Object>();
3580 3565
3581 return value; 3566 return value;
3582 } 3567 }
3583 3568
3584 3569
3585 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( 3570 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
3586 Handle<JSProxy> proxy, 3571 Handle<JSProxy> proxy,
3587 Handle<JSReceiver> receiver, 3572 Handle<JSReceiver> receiver,
3588 Handle<Name> name, 3573 Handle<Name> name,
3589 Handle<Object> value, 3574 Handle<Object> value,
3590 PropertyAttributes attributes, 3575 PropertyAttributes attributes,
3591 StrictModeFlag strict_mode, 3576 StrictMode strict_mode,
3592 bool* done) { 3577 bool* done) {
3593 Isolate* isolate = proxy->GetIsolate(); 3578 Isolate* isolate = proxy->GetIsolate();
3594 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. 3579 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
3595 3580
3596 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3581 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3597 if (name->IsSymbol()) { 3582 if (name->IsSymbol()) {
3598 *done = false; 3583 *done = false;
3599 return isolate->factory()->the_hole_value(); 3584 return isolate->factory()->the_hole_value();
3600 } 3585 }
3601 3586
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 if (hasWritable->IsTrue()) { 3634 if (hasWritable->IsTrue()) {
3650 Handle<String> writable_name = 3635 Handle<String> writable_name =
3651 isolate->factory()->InternalizeOneByteString( 3636 isolate->factory()->InternalizeOneByteString(
3652 STATIC_ASCII_VECTOR("writable_")); 3637 STATIC_ASCII_VECTOR("writable_"));
3653 Handle<Object> writable( 3638 Handle<Object> writable(
3654 v8::internal::GetProperty(isolate, desc, writable_name)); 3639 v8::internal::GetProperty(isolate, desc, writable_name));
3655 ASSERT(!isolate->has_pending_exception()); 3640 ASSERT(!isolate->has_pending_exception());
3656 ASSERT(writable->IsTrue() || writable->IsFalse()); 3641 ASSERT(writable->IsTrue() || writable->IsFalse());
3657 *done = writable->IsFalse(); 3642 *done = writable->IsFalse();
3658 if (!*done) return isolate->factory()->the_hole_value(); 3643 if (!*done) return isolate->factory()->the_hole_value();
3659 if (strict_mode == kNonStrictMode) return value; 3644 if (strict_mode == SLOPPY) return value;
3660 Handle<Object> args[] = { name, receiver }; 3645 Handle<Object> args[] = { name, receiver };
3661 Handle<Object> error = isolate->factory()->NewTypeError( 3646 Handle<Object> error = isolate->factory()->NewTypeError(
3662 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 3647 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3663 isolate->Throw(*error); 3648 isolate->Throw(*error);
3664 return Handle<Object>(); 3649 return Handle<Object>();
3665 } 3650 }
3666 3651
3667 // We have an AccessorDescriptor. 3652 // We have an AccessorDescriptor.
3668 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( 3653 Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
3669 STATIC_ASCII_VECTOR("set_")); 3654 STATIC_ASCII_VECTOR("set_"));
3670 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); 3655 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name));
3671 ASSERT(!isolate->has_pending_exception()); 3656 ASSERT(!isolate->has_pending_exception());
3672 if (!setter->IsUndefined()) { 3657 if (!setter->IsUndefined()) {
3673 // TODO(rossberg): nicer would be to cast to some JSCallable here... 3658 // TODO(rossberg): nicer would be to cast to some JSCallable here...
3674 return SetPropertyWithDefinedSetter( 3659 return SetPropertyWithDefinedSetter(
3675 receiver, Handle<JSReceiver>::cast(setter), value); 3660 receiver, Handle<JSReceiver>::cast(setter), value);
3676 } 3661 }
3677 3662
3678 if (strict_mode == kNonStrictMode) return value; 3663 if (strict_mode == SLOPPY) return value;
3679 Handle<Object> args2[] = { name, proxy }; 3664 Handle<Object> args2[] = { name, proxy };
3680 Handle<Object> error = isolate->factory()->NewTypeError( 3665 Handle<Object> error = isolate->factory()->NewTypeError(
3681 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); 3666 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
3682 isolate->Throw(*error); 3667 isolate->Throw(*error);
3683 return Handle<Object>(); 3668 return Handle<Object>();
3684 } 3669 }
3685 3670
3686 3671
3687 Handle<Object> JSProxy::DeletePropertyWithHandler( 3672 Handle<Object> JSProxy::DeletePropertyWithHandler(
3688 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { 3673 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
(...skipping 23 matching lines...) Expand all
3712 3697
3713 3698
3714 Handle<Object> JSProxy::DeleteElementWithHandler( 3699 Handle<Object> JSProxy::DeleteElementWithHandler(
3715 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { 3700 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) {
3716 Isolate* isolate = proxy->GetIsolate(); 3701 Isolate* isolate = proxy->GetIsolate();
3717 Handle<String> name = isolate->factory()->Uint32ToString(index); 3702 Handle<String> name = isolate->factory()->Uint32ToString(index);
3718 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); 3703 return JSProxy::DeletePropertyWithHandler(proxy, name, mode);
3719 } 3704 }
3720 3705
3721 3706
3722 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( 3707 PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
3723 JSReceiver* receiver_raw, 3708 Handle<JSProxy> proxy,
3724 Name* name_raw) { 3709 Handle<JSReceiver> receiver,
3725 Isolate* isolate = GetIsolate(); 3710 Handle<Name> name) {
3711 Isolate* isolate = proxy->GetIsolate();
3726 HandleScope scope(isolate); 3712 HandleScope scope(isolate);
3727 Handle<JSProxy> proxy(this);
3728 Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy.
3729 Handle<JSReceiver> receiver(receiver_raw);
3730 Handle<Object> name(name_raw, isolate);
3731 3713
3732 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3714 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3733 if (name->IsSymbol()) return ABSENT; 3715 if (name->IsSymbol()) return ABSENT;
3734 3716
3735 Handle<Object> args[] = { name }; 3717 Handle<Object> args[] = { name };
3736 Handle<Object> result = CallTrap( 3718 Handle<Object> result = proxy->CallTrap(
3737 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 3719 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
3738 if (isolate->has_pending_exception()) return NONE; 3720 if (isolate->has_pending_exception()) return NONE;
3739 3721
3740 if (result->IsUndefined()) return ABSENT; 3722 if (result->IsUndefined()) return ABSENT;
3741 3723
3742 bool has_pending_exception; 3724 bool has_pending_exception;
3743 Handle<Object> argv[] = { result }; 3725 Handle<Object> argv[] = { result };
3744 Handle<Object> desc = Execution::Call( 3726 Handle<Object> desc = Execution::Call(
3745 isolate, isolate->to_complete_property_descriptor(), result, 3727 isolate, isolate->to_complete_property_descriptor(), result,
3746 ARRAY_SIZE(argv), argv, &has_pending_exception); 3728 ARRAY_SIZE(argv), argv, &has_pending_exception);
(...skipping 14 matching lines...) Expand all
3761 if (isolate->has_pending_exception()) return NONE; 3743 if (isolate->has_pending_exception()) return NONE;
3762 if (!writable->BooleanValue()) { 3744 if (!writable->BooleanValue()) {
3763 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( 3745 Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
3764 STATIC_ASCII_VECTOR("set_")); 3746 STATIC_ASCII_VECTOR("set_"));
3765 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_n)); 3747 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_n));
3766 if (isolate->has_pending_exception()) return NONE; 3748 if (isolate->has_pending_exception()) return NONE;
3767 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); 3749 writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
3768 } 3750 }
3769 3751
3770 if (configurable->IsFalse()) { 3752 if (configurable->IsFalse()) {
3753 Handle<Object> handler(proxy->handler(), isolate);
3771 Handle<String> trap = isolate->factory()->InternalizeOneByteString( 3754 Handle<String> trap = isolate->factory()->InternalizeOneByteString(
3772 STATIC_ASCII_VECTOR("getPropertyDescriptor")); 3755 STATIC_ASCII_VECTOR("getPropertyDescriptor"));
3773 Handle<Object> args[] = { handler, trap, name }; 3756 Handle<Object> args[] = { handler, trap, name };
3774 Handle<Object> error = isolate->factory()->NewTypeError( 3757 Handle<Object> error = isolate->factory()->NewTypeError(
3775 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 3758 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
3776 isolate->Throw(*error); 3759 isolate->Throw(*error);
3777 return NONE; 3760 return NONE;
3778 } 3761 }
3779 3762
3780 int attributes = NONE; 3763 int attributes = NONE;
3781 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; 3764 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
3782 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; 3765 if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
3783 if (!writable->BooleanValue()) attributes |= READ_ONLY; 3766 if (!writable->BooleanValue()) attributes |= READ_ONLY;
3784 return static_cast<PropertyAttributes>(attributes); 3767 return static_cast<PropertyAttributes>(attributes);
3785 } 3768 }
3786 3769
3787 3770
3788 MUST_USE_RESULT PropertyAttributes JSProxy::GetElementAttributeWithHandler( 3771 PropertyAttributes JSProxy::GetElementAttributeWithHandler(
3789 JSReceiver* receiver_raw, 3772 Handle<JSProxy> proxy,
3773 Handle<JSReceiver> receiver,
3790 uint32_t index) { 3774 uint32_t index) {
3791 Isolate* isolate = GetIsolate(); 3775 Isolate* isolate = proxy->GetIsolate();
3792 HandleScope scope(isolate);
3793 Handle<JSProxy> proxy(this);
3794 Handle<JSReceiver> receiver(receiver_raw);
3795 Handle<String> name = isolate->factory()->Uint32ToString(index); 3776 Handle<String> name = isolate->factory()->Uint32ToString(index);
3796 return proxy->GetPropertyAttributeWithHandler(*receiver, *name); 3777 return GetPropertyAttributeWithHandler(proxy, receiver, name);
3797 } 3778 }
3798 3779
3799 3780
3800 void JSProxy::Fix(Handle<JSProxy> proxy) { 3781 void JSProxy::Fix(Handle<JSProxy> proxy) {
3801 Isolate* isolate = proxy->GetIsolate(); 3782 Isolate* isolate = proxy->GetIsolate();
3802 3783
3803 // Save identity hash. 3784 // Save identity hash.
3804 Handle<Object> hash(proxy->GetIdentityHash(), isolate); 3785 Handle<Object> hash(proxy->GetIdentityHash(), isolate);
3805 3786
3806 if (proxy->IsJSFunctionProxy()) { 3787 if (proxy->IsJSFunctionProxy()) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3862 IsDictionaryElementsKind(obj_kind)) { 3843 IsDictionaryElementsKind(obj_kind)) {
3863 to_kind = obj_kind; 3844 to_kind = obj_kind;
3864 } 3845 }
3865 if (IsDictionaryElementsKind(to_kind)) { 3846 if (IsDictionaryElementsKind(to_kind)) {
3866 NormalizeElements(object); 3847 NormalizeElements(object);
3867 } else { 3848 } else {
3868 TransitionElementsKind(object, to_kind); 3849 TransitionElementsKind(object, to_kind);
3869 } 3850 }
3870 map = MapAsElementsKind(map, to_kind); 3851 map = MapAsElementsKind(map, to_kind);
3871 } 3852 }
3872 int total_size = 3853 JSObject::MigrateToMap(object, map);
3873 map->NumberOfOwnDescriptors() + map->unused_property_fields();
3874 int out_of_object = total_size - map->inobject_properties();
3875 if (out_of_object != object->properties()->length()) {
3876 Isolate* isolate = object->GetIsolate();
3877 Handle<FixedArray> new_properties = isolate->factory()->CopySizeFixedArray(
3878 handle(object->properties()), out_of_object);
3879 object->set_properties(*new_properties);
3880 }
3881 object->set_map(*map);
3882 } 3854 }
3883 3855
3884 3856
3885 void JSObject::MigrateInstance(Handle<JSObject> object) { 3857 void JSObject::MigrateInstance(Handle<JSObject> object) {
3886 // Converting any field to the most specific type will cause the 3858 // Converting any field to the most specific type will cause the
3887 // GeneralizeFieldRepresentation algorithm to create the most general existing 3859 // GeneralizeFieldRepresentation algorithm to create the most general existing
3888 // transition that matches the object. This achieves what is needed. 3860 // transition that matches the object. This achieves what is needed.
3889 Handle<Map> original_map(object->map()); 3861 Handle<Map> original_map(object->map());
3890 GeneralizeFieldRepresentation( 3862 GeneralizeFieldRepresentation(
3891 object, 0, Representation::None(), ALLOW_AS_CONSTANT); 3863 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
(...skipping 26 matching lines...) Expand all
3918 int descriptor = transition_map->LastAdded(); 3890 int descriptor = transition_map->LastAdded();
3919 3891
3920 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3892 DescriptorArray* descriptors = transition_map->instance_descriptors();
3921 PropertyDetails details = descriptors->GetDetails(descriptor); 3893 PropertyDetails details = descriptors->GetDetails(descriptor);
3922 3894
3923 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3895 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3924 // AddProperty will either normalize the object, or create a new fast copy 3896 // AddProperty will either normalize the object, or create a new fast copy
3925 // of the map. If we get a fast copy of the map, all field representations 3897 // of the map. If we get a fast copy of the map, all field representations
3926 // will be tagged since the transition is omitted. 3898 // will be tagged since the transition is omitted.
3927 return JSObject::AddProperty( 3899 return JSObject::AddProperty(
3928 object, name, value, attributes, kNonStrictMode, 3900 object, name, value, attributes, SLOPPY,
3929 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, 3901 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3930 JSReceiver::OMIT_EXTENSIBILITY_CHECK, 3902 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3931 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); 3903 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3932 } 3904 }
3933 3905
3934 // Keep the target CONSTANT if the same value is stored. 3906 // Keep the target CONSTANT if the same value is stored.
3935 // TODO(verwaest): Also support keeping the placeholder 3907 // TODO(verwaest): Also support keeping the placeholder
3936 // (value->IsUninitialized) as constant. 3908 // (value->IsUninitialized) as constant.
3937 if (details.type() == CONSTANT && 3909 if (!value->FitsRepresentation(details.representation()) ||
3938 descriptors->GetValue(descriptor) == *value) { 3910 (details.type() == CONSTANT &&
3939 object->set_map(*transition_map); 3911 descriptors->GetValue(descriptor) != *value)) {
3940 return value; 3912 transition_map = Map::GeneralizeRepresentation(transition_map,
3913 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3941 } 3914 }
3942 3915
3943 Representation representation = details.representation(); 3916 JSObject::MigrateToMap(object, transition_map);
3944 3917
3945 if (!value->FitsRepresentation(representation) || 3918 // Reload.
3946 details.type() == CONSTANT) { 3919 descriptors = transition_map->instance_descriptors();
3947 transition_map = Map::GeneralizeRepresentation(transition_map, 3920 details = descriptors->GetDetails(descriptor);
3948 descriptor, value->OptimalRepresentation(), FORCE_FIELD); 3921
3949 Object* back = transition_map->GetBackPointer(); 3922 if (details.type() != FIELD) return value;
3950 if (back->IsMap()) { 3923
3951 MigrateToMap(object, handle(Map::cast(back))); 3924 int field_index = descriptors->GetFieldIndex(descriptor);
3952 } 3925 if (details.representation().IsDouble()) {
3953 descriptors = transition_map->instance_descriptors(); 3926 // Nothing more to be done.
3954 representation = descriptors->GetDetails(descriptor).representation(); 3927 if (value->IsUninitialized()) return value;
3928 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
3929 box->set_value(value->Number());
3930 } else {
3931 object->FastPropertyAtPut(field_index, *value);
3955 } 3932 }
3956 3933
3957 int field_index = descriptors->GetFieldIndex(descriptor);
3958 AddFastPropertyUsingMap(
3959 object, transition_map, name, value, field_index, representation);
3960 return value; 3934 return value;
3961 } 3935 }
3962 3936
3963 3937
3964 static void SetPropertyToField(LookupResult* lookup, 3938 static void SetPropertyToField(LookupResult* lookup,
3965 Handle<Name> name, 3939 Handle<Name> name,
3966 Handle<Object> value) { 3940 Handle<Object> value) {
3967 Representation representation = lookup->representation(); 3941 Representation representation = lookup->representation();
3968 if (!value->FitsRepresentation(representation) || 3942 if (!value->FitsRepresentation(representation) ||
3969 lookup->type() == CONSTANT) { 3943 lookup->type() == CONSTANT) {
3970 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), 3944 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
3971 lookup->GetDescriptorIndex(), 3945 lookup->GetDescriptorIndex(),
3972 value->OptimalRepresentation(), 3946 value->OptimalRepresentation(),
3973 FORCE_FIELD); 3947 FORCE_FIELD);
3974 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3948 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3975 int descriptor = lookup->GetDescriptorIndex(); 3949 int descriptor = lookup->GetDescriptorIndex();
3976 representation = desc->GetDetails(descriptor).representation(); 3950 representation = desc->GetDetails(descriptor).representation();
3977 } 3951 }
3978 3952
3979 if (FLAG_track_double_fields && representation.IsDouble()) { 3953 if (representation.IsDouble()) {
3980 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3954 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3981 lookup->GetFieldIndex().field_index())); 3955 lookup->GetFieldIndex().field_index()));
3982 storage->set_value(value->Number()); 3956 storage->set_value(value->Number());
3983 return; 3957 return;
3984 } 3958 }
3985 3959
3986 lookup->holder()->FastPropertyAtPut( 3960 lookup->holder()->FastPropertyAtPut(
3987 lookup->GetFieldIndex().field_index(), *value); 3961 lookup->GetFieldIndex().field_index(), *value);
3988 } 3962 }
3989 3963
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4030 ConvertAndSetLocalProperty(lookup, name, value, attributes); 4004 ConvertAndSetLocalProperty(lookup, name, value, attributes);
4031 } 4005 }
4032 } 4006 }
4033 4007
4034 4008
4035 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, 4009 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
4036 LookupResult* lookup, 4010 LookupResult* lookup,
4037 Handle<Name> name, 4011 Handle<Name> name,
4038 Handle<Object> value, 4012 Handle<Object> value,
4039 PropertyAttributes attributes, 4013 PropertyAttributes attributes,
4040 StrictModeFlag strict_mode, 4014 StrictMode strict_mode,
4041 StoreFromKeyed store_mode) { 4015 StoreFromKeyed store_mode) {
4042 Isolate* isolate = object->GetIsolate(); 4016 Isolate* isolate = object->GetIsolate();
4043 4017
4044 // Make sure that the top context does not change when doing callbacks or 4018 // Make sure that the top context does not change when doing callbacks or
4045 // interceptor calls. 4019 // interceptor calls.
4046 AssertNoContextChange ncc(isolate); 4020 AssertNoContextChange ncc(isolate);
4047 4021
4048 // Optimization for 2-byte strings often used as keys in a decompression 4022 // Optimization for 2-byte strings often used as keys in a decompression
4049 // dictionary. We internalize these short keys to avoid constantly 4023 // dictionary. We internalize these short keys to avoid constantly
4050 // reallocating them. 4024 // reallocating them.
4051 if (name->IsString() && !name->IsInternalizedString() && 4025 if (name->IsString() && !name->IsInternalizedString() &&
4052 Handle<String>::cast(name)->length() <= 2) { 4026 Handle<String>::cast(name)->length() <= 2) {
4053 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); 4027 name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
4054 } 4028 }
4055 4029
4056 // Check access rights if needed. 4030 // Check access rights if needed.
4057 if (object->IsAccessCheckNeeded()) { 4031 if (object->IsAccessCheckNeeded()) {
4058 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 4032 if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
4059 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, 4033 return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
4060 true, strict_mode); 4034 true, strict_mode);
4061 } 4035 }
4062 } 4036 }
4063 4037
4064 if (object->IsJSGlobalProxy()) { 4038 if (object->IsJSGlobalProxy()) {
4065 Handle<Object> proto(object->GetPrototype(), isolate); 4039 Handle<Object> proto(object->GetPrototype(), isolate);
4066 if (proto->IsNull()) return value; 4040 if (proto->IsNull()) return value;
4067 ASSERT(proto->IsJSGlobalObject()); 4041 ASSERT(proto->IsJSGlobalObject());
4068 return SetPropertyForResult(Handle<JSObject>::cast(proto), 4042 return SetPropertyForResult(Handle<JSObject>::cast(proto),
(...skipping 10 matching lines...) Expand all
4079 if (done) return result_object; 4053 if (done) return result_object;
4080 } 4054 }
4081 4055
4082 if (!lookup->IsFound()) { 4056 if (!lookup->IsFound()) {
4083 // Neither properties nor transitions found. 4057 // Neither properties nor transitions found.
4084 return AddProperty( 4058 return AddProperty(
4085 object, name, value, attributes, strict_mode, store_mode); 4059 object, name, value, attributes, strict_mode, store_mode);
4086 } 4060 }
4087 4061
4088 if (lookup->IsProperty() && lookup->IsReadOnly()) { 4062 if (lookup->IsProperty() && lookup->IsReadOnly()) {
4089 if (strict_mode == kStrictMode) { 4063 if (strict_mode == STRICT) {
4090 Handle<Object> args[] = { name, object }; 4064 Handle<Object> args[] = { name, object };
4091 Handle<Object> error = isolate->factory()->NewTypeError( 4065 Handle<Object> error = isolate->factory()->NewTypeError(
4092 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 4066 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
4093 isolate->Throw(*error); 4067 isolate->Throw(*error);
4094 return Handle<Object>(); 4068 return Handle<Object>();
4095 } else { 4069 } else {
4096 return value; 4070 return value;
4097 } 4071 }
4098 } 4072 }
4099 4073
4100 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4074 Handle<Object> old_value = isolate->factory()->the_hole_value();
4101 bool is_observed = FLAG_harmony_observation && 4075 bool is_observed = object->map()->is_observed() &&
4102 object->map()->is_observed() &&
4103 *name != isolate->heap()->hidden_string(); 4076 *name != isolate->heap()->hidden_string();
4104 if (is_observed && lookup->IsDataProperty()) { 4077 if (is_observed && lookup->IsDataProperty()) {
4105 old_value = Object::GetProperty(object, name); 4078 old_value = Object::GetProperty(object, name);
4106 } 4079 }
4107 4080
4108 // This is a real property that is not read-only, or it is a 4081 // This is a real property that is not read-only, or it is a
4109 // transition or null descriptor and there are no setters in the prototypes. 4082 // transition or null descriptor and there are no setters in the prototypes.
4110 Handle<Object> result = value; 4083 Handle<Object> result = value;
4111 switch (lookup->type()) { 4084 switch (lookup->type()) {
4112 case NORMAL: 4085 case NORMAL:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4183 AssertNoContextChange ncc(isolate); 4156 AssertNoContextChange ncc(isolate);
4184 4157
4185 LookupResult lookup(isolate); 4158 LookupResult lookup(isolate);
4186 object->LocalLookup(*name, &lookup, true); 4159 object->LocalLookup(*name, &lookup, true);
4187 if (!lookup.IsFound()) { 4160 if (!lookup.IsFound()) {
4188 object->map()->LookupTransition(*object, *name, &lookup); 4161 object->map()->LookupTransition(*object, *name, &lookup);
4189 } 4162 }
4190 4163
4191 // Check access rights if needed. 4164 // Check access rights if needed.
4192 if (object->IsAccessCheckNeeded()) { 4165 if (object->IsAccessCheckNeeded()) {
4193 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 4166 if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
4194 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, 4167 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
4195 false, kNonStrictMode); 4168 false, SLOPPY);
4196 } 4169 }
4197 } 4170 }
4198 4171
4199 if (object->IsJSGlobalProxy()) { 4172 if (object->IsJSGlobalProxy()) {
4200 Handle<Object> proto(object->GetPrototype(), isolate); 4173 Handle<Object> proto(object->GetPrototype(), isolate);
4201 if (proto->IsNull()) return value; 4174 if (proto->IsNull()) return value;
4202 ASSERT(proto->IsJSGlobalObject()); 4175 ASSERT(proto->IsJSGlobalObject());
4203 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), 4176 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
4204 name, value, attributes, value_type, mode, extensibility_check); 4177 name, value, attributes, value_type, mode, extensibility_check);
4205 } 4178 }
4206 4179
4207 if (lookup.IsFound() && 4180 if (lookup.IsFound() &&
4208 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { 4181 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
4209 object->LocalLookupRealNamedProperty(*name, &lookup); 4182 object->LocalLookupRealNamedProperty(*name, &lookup);
4210 } 4183 }
4211 4184
4212 // Check for accessor in prototype chain removed here in clone. 4185 // Check for accessor in prototype chain removed here in clone.
4213 if (!lookup.IsFound()) { 4186 if (!lookup.IsFound()) {
4214 object->map()->LookupTransition(*object, *name, &lookup); 4187 object->map()->LookupTransition(*object, *name, &lookup);
4215 TransitionFlag flag = lookup.IsFound() 4188 TransitionFlag flag = lookup.IsFound()
4216 ? OMIT_TRANSITION : INSERT_TRANSITION; 4189 ? OMIT_TRANSITION : INSERT_TRANSITION;
4217 // Neither properties nor transitions found. 4190 // Neither properties nor transitions found.
4218 return AddProperty(object, name, value, attributes, kNonStrictMode, 4191 return AddProperty(object, name, value, attributes, SLOPPY,
4219 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); 4192 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
4220 } 4193 }
4221 4194
4222 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4195 Handle<Object> old_value = isolate->factory()->the_hole_value();
4223 PropertyAttributes old_attributes = ABSENT; 4196 PropertyAttributes old_attributes = ABSENT;
4224 bool is_observed = FLAG_harmony_observation && 4197 bool is_observed = object->map()->is_observed() &&
4225 object->map()->is_observed() &&
4226 *name != isolate->heap()->hidden_string(); 4198 *name != isolate->heap()->hidden_string();
4227 if (is_observed && lookup.IsProperty()) { 4199 if (is_observed && lookup.IsProperty()) {
4228 if (lookup.IsDataProperty()) old_value = 4200 if (lookup.IsDataProperty()) old_value =
4229 Object::GetProperty(object, name); 4201 Object::GetProperty(object, name);
4230 old_attributes = lookup.GetAttributes(); 4202 old_attributes = lookup.GetAttributes();
4231 } 4203 }
4232 4204
4233 // Check of IsReadOnly removed from here in clone. 4205 // Check of IsReadOnly removed from here in clone.
4234 switch (lookup.type()) { 4206 switch (lookup.type()) {
4235 case NORMAL: 4207 case NORMAL:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4280 EnqueueChangeRecord(object, "update", name, old_value); 4252 EnqueueChangeRecord(object, "update", name, old_value);
4281 } 4253 }
4282 } 4254 }
4283 } 4255 }
4284 4256
4285 return value; 4257 return value;
4286 } 4258 }
4287 4259
4288 4260
4289 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4261 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4290 JSObject* receiver, 4262 Handle<JSObject> object,
4291 Name* name, 4263 Handle<JSObject> receiver,
4292 bool continue_search) { 4264 Handle<Name> name,
4265 bool continue_search) {
4293 // Check local property, ignore interceptor. 4266 // Check local property, ignore interceptor.
4294 LookupResult result(GetIsolate()); 4267 Isolate* isolate = object->GetIsolate();
4295 LocalLookupRealNamedProperty(name, &result); 4268 LookupResult result(isolate);
4269 object->LocalLookupRealNamedProperty(*name, &result);
4296 if (result.IsFound()) return result.GetAttributes(); 4270 if (result.IsFound()) return result.GetAttributes();
4297 4271
4298 if (continue_search) { 4272 if (continue_search) {
4299 // Continue searching via the prototype chain. 4273 // Continue searching via the prototype chain.
4300 Object* pt = GetPrototype(); 4274 Handle<Object> proto(object->GetPrototype(), isolate);
4301 if (!pt->IsNull()) { 4275 if (!proto->IsNull()) {
4302 return JSObject::cast(pt)-> 4276 return JSReceiver::GetPropertyAttributeWithReceiver(
4303 GetPropertyAttributeWithReceiver(receiver, name); 4277 Handle<JSObject>::cast(proto), receiver, name);
4304 } 4278 }
4305 } 4279 }
4306 return ABSENT; 4280 return ABSENT;
4307 } 4281 }
4308 4282
4309 4283
4310 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( 4284 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
4311 JSObject* receiver, 4285 Handle<JSObject> object,
4312 Name* name, 4286 Handle<JSObject> receiver,
4313 bool continue_search) { 4287 Handle<Name> name,
4288 bool continue_search) {
4314 // TODO(rossberg): Support symbols in the API. 4289 // TODO(rossberg): Support symbols in the API.
4315 if (name->IsSymbol()) return ABSENT; 4290 if (name->IsSymbol()) return ABSENT;
4316 4291
4317 Isolate* isolate = GetIsolate(); 4292 Isolate* isolate = object->GetIsolate();
4318 HandleScope scope(isolate); 4293 HandleScope scope(isolate);
4319 4294
4320 // Make sure that the top context does not change when doing 4295 // Make sure that the top context does not change when doing
4321 // callbacks or interceptor calls. 4296 // callbacks or interceptor calls.
4322 AssertNoContextChange ncc(isolate); 4297 AssertNoContextChange ncc(isolate);
4323 4298
4324 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 4299 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
4325 Handle<JSObject> receiver_handle(receiver); 4300 PropertyCallbackArguments args(
4326 Handle<JSObject> holder_handle(this); 4301 isolate, interceptor->data(), *receiver, *object);
4327 Handle<String> name_handle(String::cast(name));
4328 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
4329 if (!interceptor->query()->IsUndefined()) { 4302 if (!interceptor->query()->IsUndefined()) {
4330 v8::NamedPropertyQueryCallback query = 4303 v8::NamedPropertyQueryCallback query =
4331 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); 4304 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
4332 LOG(isolate, 4305 LOG(isolate,
4333 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); 4306 ApiNamedPropertyAccess("interceptor-named-has", *object, *name));
4334 v8::Handle<v8::Integer> result = 4307 v8::Handle<v8::Integer> result =
4335 args.Call(query, v8::Utils::ToLocal(name_handle)); 4308 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
4336 if (!result.IsEmpty()) { 4309 if (!result.IsEmpty()) {
4337 ASSERT(result->IsInt32()); 4310 ASSERT(result->IsInt32());
4338 return static_cast<PropertyAttributes>(result->Int32Value()); 4311 return static_cast<PropertyAttributes>(result->Int32Value());
4339 } 4312 }
4340 } else if (!interceptor->getter()->IsUndefined()) { 4313 } else if (!interceptor->getter()->IsUndefined()) {
4341 v8::NamedPropertyGetterCallback getter = 4314 v8::NamedPropertyGetterCallback getter =
4342 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); 4315 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
4343 LOG(isolate, 4316 LOG(isolate,
4344 ApiNamedPropertyAccess("interceptor-named-get-has", this, name)); 4317 ApiNamedPropertyAccess("interceptor-named-get-has", *object, *name));
4345 v8::Handle<v8::Value> result = 4318 v8::Handle<v8::Value> result =
4346 args.Call(getter, v8::Utils::ToLocal(name_handle)); 4319 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
4347 if (!result.IsEmpty()) return DONT_ENUM; 4320 if (!result.IsEmpty()) return DONT_ENUM;
4348 } 4321 }
4349 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, 4322 return GetPropertyAttributePostInterceptor(
4350 *name_handle, 4323 object, receiver, name, continue_search);
4351 continue_search);
4352 } 4324 }
4353 4325
4354 4326
4355 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( 4327 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
4356 JSReceiver* receiver, 4328 Handle<JSReceiver> object,
4357 Name* key) { 4329 Handle<JSReceiver> receiver,
4330 Handle<Name> key) {
4358 uint32_t index = 0; 4331 uint32_t index = 0;
4359 if (IsJSObject() && key->AsArrayIndex(&index)) { 4332 if (object->IsJSObject() && key->AsArrayIndex(&index)) {
4360 return JSObject::cast(this)->GetElementAttributeWithReceiver( 4333 return JSObject::GetElementAttributeWithReceiver(
4361 receiver, index, true); 4334 Handle<JSObject>::cast(object), receiver, index, true);
4362 } 4335 }
4363 // Named property. 4336 // Named property.
4364 LookupResult lookup(GetIsolate()); 4337 LookupResult lookup(object->GetIsolate());
4365 Lookup(key, &lookup); 4338 object->Lookup(*key, &lookup);
4366 return GetPropertyAttributeForResult(receiver, &lookup, key, true); 4339 return GetPropertyAttributeForResult(object, receiver, &lookup, key, true);
4367 } 4340 }
4368 4341
4369 4342
4370 PropertyAttributes JSReceiver::GetPropertyAttributeForResult( 4343 PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
4371 JSReceiver* receiver, 4344 Handle<JSReceiver> object,
4345 Handle<JSReceiver> receiver,
4372 LookupResult* lookup, 4346 LookupResult* lookup,
4373 Name* name, 4347 Handle<Name> name,
4374 bool continue_search) { 4348 bool continue_search) {
4375 // Check access rights if needed. 4349 // Check access rights if needed.
4376 if (IsAccessCheckNeeded()) { 4350 if (object->IsAccessCheckNeeded()) {
4377 JSObject* this_obj = JSObject::cast(this); 4351 Heap* heap = object->GetHeap();
4378 Heap* heap = GetHeap(); 4352 Handle<JSObject> obj = Handle<JSObject>::cast(object);
4379 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { 4353 if (!heap->isolate()->MayNamedAccessWrapper(obj, name, v8::ACCESS_HAS)) {
4380 return this_obj->GetPropertyAttributeWithFailedAccessCheck( 4354 return JSObject::GetPropertyAttributeWithFailedAccessCheck(
4381 receiver, lookup, name, continue_search); 4355 obj, lookup, name, continue_search);
4382 } 4356 }
4383 } 4357 }
4384 if (lookup->IsFound()) { 4358 if (lookup->IsFound()) {
4385 switch (lookup->type()) { 4359 switch (lookup->type()) {
4386 case NORMAL: // fall through 4360 case NORMAL: // fall through
4387 case FIELD: 4361 case FIELD:
4388 case CONSTANT: 4362 case CONSTANT:
4389 case CALLBACKS: 4363 case CALLBACKS:
4390 return lookup->GetAttributes(); 4364 return lookup->GetAttributes();
4391 case HANDLER: { 4365 case HANDLER: {
4392 return JSProxy::cast(lookup->proxy())->GetPropertyAttributeWithHandler( 4366 return JSProxy::GetPropertyAttributeWithHandler(
4393 receiver, name); 4367 handle(lookup->proxy()), receiver, name);
4394 } 4368 }
4395 case INTERCEPTOR: 4369 case INTERCEPTOR:
4396 return lookup->holder()->GetPropertyAttributeWithInterceptor( 4370 return JSObject::GetPropertyAttributeWithInterceptor(
4397 JSObject::cast(receiver), name, continue_search); 4371 handle(lookup->holder()),
4372 Handle<JSObject>::cast(receiver),
4373 name,
4374 continue_search);
4398 case TRANSITION: 4375 case TRANSITION:
4399 case NONEXISTENT: 4376 case NONEXISTENT:
4400 UNREACHABLE(); 4377 UNREACHABLE();
4401 } 4378 }
4402 } 4379 }
4403 return ABSENT; 4380 return ABSENT;
4404 } 4381 }
4405 4382
4406 4383
4407 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(Name* name) { 4384 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(
4385 Handle<JSReceiver> object, Handle<Name> name) {
4408 // Check whether the name is an array index. 4386 // Check whether the name is an array index.
4409 uint32_t index = 0; 4387 uint32_t index = 0;
4410 if (IsJSObject() && name->AsArrayIndex(&index)) { 4388 if (object->IsJSObject() && name->AsArrayIndex(&index)) {
4411 return GetLocalElementAttribute(index); 4389 return GetLocalElementAttribute(object, index);
4412 } 4390 }
4413 // Named property. 4391 // Named property.
4414 LookupResult lookup(GetIsolate()); 4392 LookupResult lookup(object->GetIsolate());
4415 LocalLookup(name, &lookup, true); 4393 object->LocalLookup(*name, &lookup, true);
4416 return GetPropertyAttributeForResult(this, &lookup, name, false); 4394 return GetPropertyAttributeForResult(object, object, &lookup, name, false);
4417 } 4395 }
4418 4396
4419 4397
4420 PropertyAttributes JSObject::GetElementAttributeWithReceiver( 4398 PropertyAttributes JSObject::GetElementAttributeWithReceiver(
4421 JSReceiver* receiver, uint32_t index, bool continue_search) { 4399 Handle<JSObject> object,
4422 Isolate* isolate = GetIsolate(); 4400 Handle<JSReceiver> receiver,
4401 uint32_t index,
4402 bool continue_search) {
4403 Isolate* isolate = object->GetIsolate();
4423 4404
4424 // Check access rights if needed. 4405 // Check access rights if needed.
4425 if (IsAccessCheckNeeded()) { 4406 if (object->IsAccessCheckNeeded()) {
4426 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 4407 if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
4427 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 4408 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
4428 return ABSENT; 4409 return ABSENT;
4429 } 4410 }
4430 } 4411 }
4431 4412
4432 if (IsJSGlobalProxy()) { 4413 if (object->IsJSGlobalProxy()) {
4433 Object* proto = GetPrototype(); 4414 Handle<Object> proto(object->GetPrototype(), isolate);
4434 if (proto->IsNull()) return ABSENT; 4415 if (proto->IsNull()) return ABSENT;
4435 ASSERT(proto->IsJSGlobalObject()); 4416 ASSERT(proto->IsJSGlobalObject());
4436 return JSObject::cast(proto)->GetElementAttributeWithReceiver( 4417 return JSObject::GetElementAttributeWithReceiver(
4437 receiver, index, continue_search); 4418 Handle<JSObject>::cast(proto), receiver, index, continue_search);
4438 } 4419 }
4439 4420
4440 // Check for lookup interceptor except when bootstrapping. 4421 // Check for lookup interceptor except when bootstrapping.
4441 if (HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { 4422 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
4442 return GetElementAttributeWithInterceptor(receiver, index, continue_search); 4423 return JSObject::GetElementAttributeWithInterceptor(
4424 object, receiver, index, continue_search);
4443 } 4425 }
4444 4426
4445 return GetElementAttributeWithoutInterceptor( 4427 return GetElementAttributeWithoutInterceptor(
4446 receiver, index, continue_search); 4428 object, receiver, index, continue_search);
4447 } 4429 }
4448 4430
4449 4431
4450 PropertyAttributes JSObject::GetElementAttributeWithInterceptor( 4432 PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
4451 JSReceiver* receiver, uint32_t index, bool continue_search) { 4433 Handle<JSObject> object,
4452 Isolate* isolate = GetIsolate(); 4434 Handle<JSReceiver> receiver,
4435 uint32_t index,
4436 bool continue_search) {
4437 Isolate* isolate = object->GetIsolate();
4453 HandleScope scope(isolate); 4438 HandleScope scope(isolate);
4454 4439
4455 // Make sure that the top context does not change when doing 4440 // Make sure that the top context does not change when doing
4456 // callbacks or interceptor calls. 4441 // callbacks or interceptor calls.
4457 AssertNoContextChange ncc(isolate); 4442 AssertNoContextChange ncc(isolate);
4458 4443
4459 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 4444 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4460 Handle<JSReceiver> hreceiver(receiver); 4445 PropertyCallbackArguments args(
4461 Handle<JSObject> holder(this); 4446 isolate, interceptor->data(), *receiver, *object);
4462 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
4463 if (!interceptor->query()->IsUndefined()) { 4447 if (!interceptor->query()->IsUndefined()) {
4464 v8::IndexedPropertyQueryCallback query = 4448 v8::IndexedPropertyQueryCallback query =
4465 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); 4449 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4466 LOG(isolate, 4450 LOG(isolate,
4467 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); 4451 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
4468 v8::Handle<v8::Integer> result = args.Call(query, index); 4452 v8::Handle<v8::Integer> result = args.Call(query, index);
4469 if (!result.IsEmpty()) 4453 if (!result.IsEmpty())
4470 return static_cast<PropertyAttributes>(result->Int32Value()); 4454 return static_cast<PropertyAttributes>(result->Int32Value());
4471 } else if (!interceptor->getter()->IsUndefined()) { 4455 } else if (!interceptor->getter()->IsUndefined()) {
4472 v8::IndexedPropertyGetterCallback getter = 4456 v8::IndexedPropertyGetterCallback getter =
4473 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); 4457 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4474 LOG(isolate, 4458 LOG(isolate,
4475 ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index)); 4459 ApiIndexedPropertyAccess(
4460 "interceptor-indexed-get-has", *object, index));
4476 v8::Handle<v8::Value> result = args.Call(getter, index); 4461 v8::Handle<v8::Value> result = args.Call(getter, index);
4477 if (!result.IsEmpty()) return NONE; 4462 if (!result.IsEmpty()) return NONE;
4478 } 4463 }
4479 4464
4480 return holder->GetElementAttributeWithoutInterceptor( 4465 return GetElementAttributeWithoutInterceptor(
4481 *hreceiver, index, continue_search); 4466 object, receiver, index, continue_search);
4482 } 4467 }
4483 4468
4484 4469
4485 PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor( 4470 PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
4486 JSReceiver* receiver, uint32_t index, bool continue_search) { 4471 Handle<JSObject> object,
4487 PropertyAttributes attr = GetElementsAccessor()->GetAttributes( 4472 Handle<JSReceiver> receiver,
4488 receiver, this, index); 4473 uint32_t index,
4474 bool continue_search) {
4475 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
4476 *receiver, *object, index);
4489 if (attr != ABSENT) return attr; 4477 if (attr != ABSENT) return attr;
4490 4478
4491 // Handle [] on String objects. 4479 // Handle [] on String objects.
4492 if (IsStringObjectWithCharacterAt(index)) { 4480 if (object->IsStringObjectWithCharacterAt(index)) {
4493 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 4481 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
4494 } 4482 }
4495 4483
4496 if (!continue_search) return ABSENT; 4484 if (!continue_search) return ABSENT;
4497 4485
4498 Object* pt = GetPrototype(); 4486 Handle<Object> proto(object->GetPrototype(), object->GetIsolate());
4499 if (pt->IsJSProxy()) { 4487 if (proto->IsJSProxy()) {
4500 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. 4488 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
4501 return JSProxy::cast(pt)->GetElementAttributeWithHandler(receiver, index); 4489 return JSProxy::GetElementAttributeWithHandler(
4490 Handle<JSProxy>::cast(proto), receiver, index);
4502 } 4491 }
4503 if (pt->IsNull()) return ABSENT; 4492 if (proto->IsNull()) return ABSENT;
4504 return JSObject::cast(pt)->GetElementAttributeWithReceiver( 4493 return GetElementAttributeWithReceiver(
4505 receiver, index, true); 4494 Handle<JSObject>::cast(proto), receiver, index, true);
4506 } 4495 }
4507 4496
4508 4497
4509 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, 4498 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache,
4510 Handle<JSObject> obj, 4499 Handle<JSObject> obj,
4511 PropertyNormalizationMode mode) { 4500 PropertyNormalizationMode mode) {
4512 int index = obj->map()->Hash() % kEntries; 4501 int index = obj->map()->Hash() % kEntries;
4513 Handle<Object> result = handle(cache->get(index), cache->GetIsolate()); 4502 Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
4514 if (result->IsMap() && 4503 if (result->IsMap() &&
4515 Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(), 4504 Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(),
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4738 } 4727 }
4739 4728
4740 4729
4741 MaybeObject* JSObject::NormalizeElements() { 4730 MaybeObject* JSObject::NormalizeElements() {
4742 ASSERT(!HasExternalArrayElements()); 4731 ASSERT(!HasExternalArrayElements());
4743 4732
4744 // Find the backing store. 4733 // Find the backing store.
4745 FixedArrayBase* array = FixedArrayBase::cast(elements()); 4734 FixedArrayBase* array = FixedArrayBase::cast(elements());
4746 Map* old_map = array->map(); 4735 Map* old_map = array->map();
4747 bool is_arguments = 4736 bool is_arguments =
4748 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); 4737 (old_map == old_map->GetHeap()->sloppy_arguments_elements_map());
4749 if (is_arguments) { 4738 if (is_arguments) {
4750 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); 4739 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
4751 } 4740 }
4752 if (array->IsDictionary()) return array; 4741 if (array->IsDictionary()) return array;
4753 4742
4754 ASSERT(HasFastSmiOrObjectElements() || 4743 ASSERT(HasFastSmiOrObjectElements() ||
4755 HasFastDoubleElements() || 4744 HasFastDoubleElements() ||
4756 HasFastArgumentsElements()); 4745 HasFastArgumentsElements());
4757 // Compute the effective length and allocate a new backing store. 4746 // Compute the effective length and allocate a new backing store.
4758 int length = IsJSArray() 4747 int length = IsJSArray()
(...skipping 14 matching lines...) Expand all
4773 // Switch to using the dictionary as the backing storage for elements. 4762 // Switch to using the dictionary as the backing storage for elements.
4774 if (is_arguments) { 4763 if (is_arguments) {
4775 FixedArray::cast(elements())->set(1, dictionary); 4764 FixedArray::cast(elements())->set(1, dictionary);
4776 } else { 4765 } else {
4777 // Set the new map first to satify the elements type assert in 4766 // Set the new map first to satify the elements type assert in
4778 // set_elements(). 4767 // set_elements().
4779 Map* new_map; 4768 Map* new_map;
4780 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), 4769 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(),
4781 DICTIONARY_ELEMENTS); 4770 DICTIONARY_ELEMENTS);
4782 if (!maybe->To(&new_map)) return maybe; 4771 if (!maybe->To(&new_map)) return maybe;
4772 // TODO(verwaest): Replace by MigrateToMap.
4783 set_map(new_map); 4773 set_map(new_map);
4784 set_elements(dictionary); 4774 set_elements(dictionary);
4785 } 4775 }
4786 4776
4787 old_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> 4777 old_map->GetHeap()->isolate()->counters()->elements_to_dictionary()->
4788 Increment(); 4778 Increment();
4789 4779
4790 #ifdef DEBUG 4780 #ifdef DEBUG
4791 if (FLAG_trace_normalization) { 4781 if (FLAG_trace_normalization) {
4792 PrintF("Object elements have been normalized:\n"); 4782 PrintF("Object elements have been normalized:\n");
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
4953 4943
4954 // We never delete (inline-stored) identity hashes. 4944 // We never delete (inline-stored) identity hashes.
4955 ASSERT(*key != *isolate->factory()->identity_hash_string()); 4945 ASSERT(*key != *isolate->factory()->identity_hash_string());
4956 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; 4946 if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
4957 4947
4958 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); 4948 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
4959 ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value()); 4949 ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value());
4960 } 4950 }
4961 4951
4962 4952
4963 bool JSObject::HasHiddenProperties() { 4953 bool JSObject::HasHiddenProperties(Handle<JSObject> object) {
4964 return GetPropertyAttributePostInterceptor(this, 4954 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
4965 GetHeap()->hidden_string(), 4955 return GetPropertyAttributePostInterceptor(
4966 false) != ABSENT; 4956 object, object, hidden, false) != ABSENT;
4967 } 4957 }
4968 4958
4969 4959
4970 Object* JSObject::GetHiddenPropertiesHashTable() { 4960 Object* JSObject::GetHiddenPropertiesHashTable() {
4971 ASSERT(!IsJSGlobalProxy()); 4961 ASSERT(!IsJSGlobalProxy());
4972 if (HasFastProperties()) { 4962 if (HasFastProperties()) {
4973 // If the object has fast properties, check whether the first slot 4963 // If the object has fast properties, check whether the first slot
4974 // in the descriptor array matches the hidden string. Since the 4964 // in the descriptor array matches the hidden string. Since the
4975 // hidden strings hash code is zero (and no other name has hash 4965 // hidden strings hash code is zero (and no other name has hash
4976 // code zero) it will always occupy the first entry if present. 4966 // code zero) it will always occupy the first entry if present.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5037 5027
5038 5028
5039 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, 5029 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
5040 Handle<Object> value) { 5030 Handle<Object> value) {
5041 ASSERT(!object->IsJSGlobalProxy()); 5031 ASSERT(!object->IsJSGlobalProxy());
5042 5032
5043 Isolate* isolate = object->GetIsolate(); 5033 Isolate* isolate = object->GetIsolate();
5044 5034
5045 // We can store the identity hash inline iff there is no backing store 5035 // We can store the identity hash inline iff there is no backing store
5046 // for hidden properties yet. 5036 // for hidden properties yet.
5047 ASSERT(object->HasHiddenProperties() != value->IsSmi()); 5037 ASSERT(JSObject::HasHiddenProperties(object) != value->IsSmi());
5048 if (object->HasFastProperties()) { 5038 if (object->HasFastProperties()) {
5049 // If the object has fast properties, check whether the first slot 5039 // If the object has fast properties, check whether the first slot
5050 // in the descriptor array matches the hidden string. Since the 5040 // in the descriptor array matches the hidden string. Since the
5051 // hidden strings hash code is zero (and no other name has hash 5041 // hidden strings hash code is zero (and no other name has hash
5052 // code zero) it will always occupy the first entry if present. 5042 // code zero) it will always occupy the first entry if present.
5053 DescriptorArray* descriptors = object->map()->instance_descriptors(); 5043 DescriptorArray* descriptors = object->map()->instance_descriptors();
5054 if (descriptors->number_of_descriptors() > 0) { 5044 if (descriptors->number_of_descriptors() > 0) {
5055 int sorted_index = descriptors->GetSortedKeyIndex(0); 5045 int sorted_index = descriptors->GetSortedKeyIndex(0);
5056 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() 5046 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string()
5057 && sorted_index < object->map()->NumberOfOwnDescriptors()) { 5047 && sorted_index < object->map()->NumberOfOwnDescriptors()) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
5168 5158
5169 5159
5170 Handle<Object> JSObject::DeleteElement(Handle<JSObject> object, 5160 Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
5171 uint32_t index, 5161 uint32_t index,
5172 DeleteMode mode) { 5162 DeleteMode mode) {
5173 Isolate* isolate = object->GetIsolate(); 5163 Isolate* isolate = object->GetIsolate();
5174 Factory* factory = isolate->factory(); 5164 Factory* factory = isolate->factory();
5175 5165
5176 // Check access rights if needed. 5166 // Check access rights if needed.
5177 if (object->IsAccessCheckNeeded() && 5167 if (object->IsAccessCheckNeeded() &&
5178 !isolate->MayIndexedAccess(*object, index, v8::ACCESS_DELETE)) { 5168 !isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_DELETE)) {
5179 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE); 5169 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
5180 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5170 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5181 return factory->false_value(); 5171 return factory->false_value();
5182 } 5172 }
5183 5173
5184 if (object->IsStringObjectWithCharacterAt(index)) { 5174 if (object->IsStringObjectWithCharacterAt(index)) {
5185 if (mode == STRICT_DELETION) { 5175 if (mode == STRICT_DELETION) {
5186 // Deleting a non-configurable property in strict mode. 5176 // Deleting a non-configurable property in strict mode.
5187 Handle<Object> name = factory->NewNumberFromUint(index); 5177 Handle<Object> name = factory->NewNumberFromUint(index);
5188 Handle<Object> args[2] = { name, object }; 5178 Handle<Object> args[2] = { name, object };
5189 Handle<Object> error = 5179 Handle<Object> error =
5190 factory->NewTypeError("strict_delete_property", 5180 factory->NewTypeError("strict_delete_property",
5191 HandleVector(args, 2)); 5181 HandleVector(args, 2));
5192 isolate->Throw(*error); 5182 isolate->Throw(*error);
5193 return Handle<Object>(); 5183 return Handle<Object>();
5194 } 5184 }
5195 return factory->false_value(); 5185 return factory->false_value();
5196 } 5186 }
5197 5187
5198 if (object->IsJSGlobalProxy()) { 5188 if (object->IsJSGlobalProxy()) {
5199 Handle<Object> proto(object->GetPrototype(), isolate); 5189 Handle<Object> proto(object->GetPrototype(), isolate);
5200 if (proto->IsNull()) return factory->false_value(); 5190 if (proto->IsNull()) return factory->false_value();
5201 ASSERT(proto->IsJSGlobalObject()); 5191 ASSERT(proto->IsJSGlobalObject());
5202 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); 5192 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5203 } 5193 }
5204 5194
5205 Handle<Object> old_value; 5195 Handle<Object> old_value;
5206 bool should_enqueue_change_record = false; 5196 bool should_enqueue_change_record = false;
5207 if (FLAG_harmony_observation && object->map()->is_observed()) { 5197 if (object->map()->is_observed()) {
5208 should_enqueue_change_record = HasLocalElement(object, index); 5198 should_enqueue_change_record = HasLocalElement(object, index);
5209 if (should_enqueue_change_record) { 5199 if (should_enqueue_change_record) {
5210 old_value = object->GetLocalElementAccessorPair(index) != NULL 5200 old_value = object->GetLocalElementAccessorPair(index) != NULL
5211 ? Handle<Object>::cast(factory->the_hole_value()) 5201 ? Handle<Object>::cast(factory->the_hole_value())
5212 : Object::GetElement(isolate, object, index); 5202 : Object::GetElement(isolate, object, index);
5213 } 5203 }
5214 } 5204 }
5215 5205
5216 // Skip interceptor if forcing deletion. 5206 // Skip interceptor if forcing deletion.
5217 Handle<Object> result; 5207 Handle<Object> result;
(...skipping 14 matching lines...) Expand all
5232 5222
5233 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object, 5223 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
5234 Handle<Name> name, 5224 Handle<Name> name,
5235 DeleteMode mode) { 5225 DeleteMode mode) {
5236 Isolate* isolate = object->GetIsolate(); 5226 Isolate* isolate = object->GetIsolate();
5237 // ECMA-262, 3rd, 8.6.2.5 5227 // ECMA-262, 3rd, 8.6.2.5
5238 ASSERT(name->IsName()); 5228 ASSERT(name->IsName());
5239 5229
5240 // Check access rights if needed. 5230 // Check access rights if needed.
5241 if (object->IsAccessCheckNeeded() && 5231 if (object->IsAccessCheckNeeded() &&
5242 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) { 5232 !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_DELETE)) {
5243 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE); 5233 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
5244 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5234 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5245 return isolate->factory()->false_value(); 5235 return isolate->factory()->false_value();
5246 } 5236 }
5247 5237
5248 if (object->IsJSGlobalProxy()) { 5238 if (object->IsJSGlobalProxy()) {
5249 Object* proto = object->GetPrototype(); 5239 Object* proto = object->GetPrototype();
5250 if (proto->IsNull()) return isolate->factory()->false_value(); 5240 if (proto->IsNull()) return isolate->factory()->false_value();
5251 ASSERT(proto->IsJSGlobalObject()); 5241 ASSERT(proto->IsJSGlobalObject());
5252 return JSGlobalObject::DeleteProperty( 5242 return JSGlobalObject::DeleteProperty(
5253 handle(JSGlobalObject::cast(proto)), name, mode); 5243 handle(JSGlobalObject::cast(proto)), name, mode);
(...skipping 14 matching lines...) Expand all
5268 Handle<Object> args[2] = { name, object }; 5258 Handle<Object> args[2] = { name, object };
5269 Handle<Object> error = isolate->factory()->NewTypeError( 5259 Handle<Object> error = isolate->factory()->NewTypeError(
5270 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); 5260 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
5271 isolate->Throw(*error); 5261 isolate->Throw(*error);
5272 return Handle<Object>(); 5262 return Handle<Object>();
5273 } 5263 }
5274 return isolate->factory()->false_value(); 5264 return isolate->factory()->false_value();
5275 } 5265 }
5276 5266
5277 Handle<Object> old_value = isolate->factory()->the_hole_value(); 5267 Handle<Object> old_value = isolate->factory()->the_hole_value();
5278 bool is_observed = FLAG_harmony_observation && 5268 bool is_observed = object->map()->is_observed() &&
5279 object->map()->is_observed() &&
5280 *name != isolate->heap()->hidden_string(); 5269 *name != isolate->heap()->hidden_string();
5281 if (is_observed && lookup.IsDataProperty()) { 5270 if (is_observed && lookup.IsDataProperty()) {
5282 old_value = Object::GetProperty(object, name); 5271 old_value = Object::GetProperty(object, name);
5283 } 5272 }
5284 Handle<Object> result; 5273 Handle<Object> result;
5285 5274
5286 // Check for interceptor. 5275 // Check for interceptor.
5287 if (lookup.IsInterceptor()) { 5276 if (lookup.IsInterceptor()) {
5288 // Skip interceptor if forcing a deletion. 5277 // Skip interceptor if forcing a deletion.
5289 if (mode == FORCE_DELETION) { 5278 if (mode == FORCE_DELETION) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 case FAST_SMI_ELEMENTS: 5380 case FAST_SMI_ELEMENTS:
5392 case FAST_HOLEY_SMI_ELEMENTS: 5381 case FAST_HOLEY_SMI_ELEMENTS:
5393 break; 5382 break;
5394 case FAST_ELEMENTS: 5383 case FAST_ELEMENTS:
5395 case FAST_HOLEY_ELEMENTS: 5384 case FAST_HOLEY_ELEMENTS:
5396 case DICTIONARY_ELEMENTS: { 5385 case DICTIONARY_ELEMENTS: {
5397 FixedArray* elements = FixedArray::cast(this->elements()); 5386 FixedArray* elements = FixedArray::cast(this->elements());
5398 if (ReferencesObjectFromElements(elements, kind, obj)) return true; 5387 if (ReferencesObjectFromElements(elements, kind, obj)) return true;
5399 break; 5388 break;
5400 } 5389 }
5401 case NON_STRICT_ARGUMENTS_ELEMENTS: { 5390 case SLOPPY_ARGUMENTS_ELEMENTS: {
5402 FixedArray* parameter_map = FixedArray::cast(elements()); 5391 FixedArray* parameter_map = FixedArray::cast(elements());
5403 // Check the mapped parameters. 5392 // Check the mapped parameters.
5404 int length = parameter_map->length(); 5393 int length = parameter_map->length();
5405 for (int i = 2; i < length; ++i) { 5394 for (int i = 2; i < length; ++i) {
5406 Object* value = parameter_map->get(i); 5395 Object* value = parameter_map->get(i);
5407 if (!value->IsTheHole() && value == obj) return true; 5396 if (!value->IsTheHole() && value == obj) return true;
5408 } 5397 }
5409 // Check the arguments. 5398 // Check the arguments.
5410 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 5399 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
5411 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : 5400 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS :
5412 FAST_HOLEY_ELEMENTS; 5401 FAST_HOLEY_ELEMENTS;
5413 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; 5402 if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
5414 break; 5403 break;
5415 } 5404 }
5416 } 5405 }
5417 5406
5418 // For functions check the context. 5407 // For functions check the context.
5419 if (IsJSFunction()) { 5408 if (IsJSFunction()) {
5420 // Get the constructor function for arguments array. 5409 // Get the constructor function for arguments array.
5421 JSObject* arguments_boilerplate = 5410 JSObject* arguments_boilerplate =
5422 heap->isolate()->context()->native_context()-> 5411 heap->isolate()->context()->native_context()->
5423 arguments_boilerplate(); 5412 sloppy_arguments_boilerplate();
5424 JSFunction* arguments_function = 5413 JSFunction* arguments_function =
5425 JSFunction::cast(arguments_boilerplate->map()->constructor()); 5414 JSFunction::cast(arguments_boilerplate->map()->constructor());
5426 5415
5427 // Get the context and don't check if it is the native context. 5416 // Get the context and don't check if it is the native context.
5428 JSFunction* f = JSFunction::cast(this); 5417 JSFunction* f = JSFunction::cast(this);
5429 Context* context = f->context(); 5418 Context* context = f->context();
5430 if (context->IsNativeContext()) { 5419 if (context->IsNativeContext()) {
5431 return false; 5420 return false;
5432 } 5421 }
5433 5422
(...skipping 29 matching lines...) Expand all
5463 return false; 5452 return false;
5464 } 5453 }
5465 5454
5466 5455
5467 Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { 5456 Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
5468 Isolate* isolate = object->GetIsolate(); 5457 Isolate* isolate = object->GetIsolate();
5469 5458
5470 if (!object->map()->is_extensible()) return object; 5459 if (!object->map()->is_extensible()) return object;
5471 5460
5472 if (object->IsAccessCheckNeeded() && 5461 if (object->IsAccessCheckNeeded() &&
5473 !isolate->MayNamedAccess(*object, 5462 !isolate->MayNamedAccessWrapper(object,
5474 isolate->heap()->undefined_value(), 5463 isolate->factory()->undefined_value(),
5475 v8::ACCESS_KEYS)) { 5464 v8::ACCESS_KEYS)) {
5476 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); 5465 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
5477 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5466 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5478 return isolate->factory()->false_value(); 5467 return isolate->factory()->false_value();
5479 } 5468 }
5480 5469
5481 if (object->IsJSGlobalProxy()) { 5470 if (object->IsJSGlobalProxy()) {
5482 Handle<Object> proto(object->GetPrototype(), isolate); 5471 Handle<Object> proto(object->GetPrototype(), isolate);
5483 if (proto->IsNull()) return object; 5472 if (proto->IsNull()) return object;
5484 ASSERT(proto->IsJSGlobalObject()); 5473 ASSERT(proto->IsJSGlobalObject());
5485 return PreventExtensions(Handle<JSObject>::cast(proto)); 5474 return PreventExtensions(Handle<JSObject>::cast(proto));
5486 } 5475 }
(...skipping 15 matching lines...) Expand all
5502 5491
5503 // Make sure that we never go back to fast case. 5492 // Make sure that we never go back to fast case.
5504 dictionary->set_requires_slow_elements(); 5493 dictionary->set_requires_slow_elements();
5505 5494
5506 // Do a map transition, other objects with this map may still 5495 // Do a map transition, other objects with this map may still
5507 // be extensible. 5496 // be extensible.
5508 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5497 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5509 Handle<Map> new_map = Map::Copy(handle(object->map())); 5498 Handle<Map> new_map = Map::Copy(handle(object->map()));
5510 5499
5511 new_map->set_is_extensible(false); 5500 new_map->set_is_extensible(false);
5512 object->set_map(*new_map); 5501 JSObject::MigrateToMap(object, new_map);
5513 ASSERT(!object->map()->is_extensible()); 5502 ASSERT(!object->map()->is_extensible());
5514 5503
5515 if (FLAG_harmony_observation && object->map()->is_observed()) { 5504 if (object->map()->is_observed()) {
5516 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), 5505 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
5517 isolate->factory()->the_hole_value()); 5506 isolate->factory()->the_hole_value());
5518 } 5507 }
5519 return object; 5508 return object;
5520 } 5509 }
5521 5510
5522 5511
5523 template<typename Dictionary> 5512 template<typename Dictionary>
5524 static void FreezeDictionary(Dictionary* dictionary) { 5513 static void FreezeDictionary(Dictionary* dictionary) {
5525 int capacity = dictionary->Capacity(); 5514 int capacity = dictionary->Capacity();
5526 for (int i = 0; i < capacity; i++) { 5515 for (int i = 0; i < capacity; i++) {
5527 Object* k = dictionary->KeyAt(i); 5516 Object* k = dictionary->KeyAt(i);
5528 if (dictionary->IsKey(k)) { 5517 if (dictionary->IsKey(k)) {
5529 PropertyDetails details = dictionary->DetailsAt(i); 5518 PropertyDetails details = dictionary->DetailsAt(i);
5530 int attrs = DONT_DELETE; 5519 int attrs = DONT_DELETE;
5531 // READ_ONLY is an invalid attribute for JS setters/getters. 5520 // READ_ONLY is an invalid attribute for JS setters/getters.
5532 if (details.type() != CALLBACKS || 5521 if (details.type() != CALLBACKS ||
5533 !dictionary->ValueAt(i)->IsAccessorPair()) { 5522 !dictionary->ValueAt(i)->IsAccessorPair()) {
5534 attrs |= READ_ONLY; 5523 attrs |= READ_ONLY;
5535 } 5524 }
5536 details = details.CopyAddAttributes( 5525 details = details.CopyAddAttributes(
5537 static_cast<PropertyAttributes>(attrs)); 5526 static_cast<PropertyAttributes>(attrs));
5538 dictionary->DetailsAtPut(i, details); 5527 dictionary->DetailsAtPut(i, details);
5539 } 5528 }
5540 } 5529 }
5541 } 5530 }
5542 5531
5543 5532
5544 Handle<Object> JSObject::Freeze(Handle<JSObject> object) { 5533 Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
5545 // Freezing non-strict arguments should be handled elsewhere. 5534 // Freezing sloppy arguments should be handled elsewhere.
5546 ASSERT(!object->HasNonStrictArgumentsElements()); 5535 ASSERT(!object->HasSloppyArgumentsElements());
5547 ASSERT(!object->map()->is_observed()); 5536 ASSERT(!object->map()->is_observed());
5548 5537
5549 if (object->map()->is_frozen()) return object; 5538 if (object->map()->is_frozen()) return object;
5550 5539
5551 Isolate* isolate = object->GetIsolate(); 5540 Isolate* isolate = object->GetIsolate();
5552 if (object->IsAccessCheckNeeded() && 5541 if (object->IsAccessCheckNeeded() &&
5553 !isolate->MayNamedAccess(*object, 5542 !isolate->MayNamedAccessWrapper(object,
5554 isolate->heap()->undefined_value(), 5543 isolate->factory()->undefined_value(),
5555 v8::ACCESS_KEYS)) { 5544 v8::ACCESS_KEYS)) {
5556 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); 5545 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
5557 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5546 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5558 return isolate->factory()->false_value(); 5547 return isolate->factory()->false_value();
5559 } 5548 }
5560 5549
5561 if (object->IsJSGlobalProxy()) { 5550 if (object->IsJSGlobalProxy()) {
5562 Handle<Object> proto(object->GetPrototype(), isolate); 5551 Handle<Object> proto(object->GetPrototype(), isolate);
5563 if (proto->IsNull()) return object; 5552 if (proto->IsNull()) return object;
5564 ASSERT(proto->IsJSGlobalObject()); 5553 ASSERT(proto->IsJSGlobalObject());
5565 return Freeze(Handle<JSObject>::cast(proto)); 5554 return Freeze(Handle<JSObject>::cast(proto));
5566 } 5555 }
(...skipping 28 matching lines...) Expand all
5595 // No existing elements, use a pre-allocated empty backing store 5584 // No existing elements, use a pre-allocated empty backing store
5596 new_element_dictionary = 5585 new_element_dictionary =
5597 isolate->factory()->empty_slow_element_dictionary(); 5586 isolate->factory()->empty_slow_element_dictionary();
5598 } 5587 }
5599 } 5588 }
5600 5589
5601 LookupResult result(isolate); 5590 LookupResult result(isolate);
5602 Handle<Map> old_map(object->map()); 5591 Handle<Map> old_map(object->map());
5603 old_map->LookupTransition(*object, isolate->heap()->frozen_symbol(), &result); 5592 old_map->LookupTransition(*object, isolate->heap()->frozen_symbol(), &result);
5604 if (result.IsTransition()) { 5593 if (result.IsTransition()) {
5605 Map* transition_map = result.GetTransitionTarget(); 5594 Handle<Map> transition_map(result.GetTransitionTarget());
5606 ASSERT(transition_map->has_dictionary_elements()); 5595 ASSERT(transition_map->has_dictionary_elements());
5607 ASSERT(transition_map->is_frozen()); 5596 ASSERT(transition_map->is_frozen());
5608 ASSERT(!transition_map->is_extensible()); 5597 ASSERT(!transition_map->is_extensible());
5609 object->set_map(transition_map); 5598 JSObject::MigrateToMap(object, transition_map);
5610 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5599 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5611 // Create a new descriptor array with fully-frozen properties 5600 // Create a new descriptor array with fully-frozen properties
5612 int num_descriptors = old_map->NumberOfOwnDescriptors(); 5601 int num_descriptors = old_map->NumberOfOwnDescriptors();
5613 Handle<DescriptorArray> new_descriptors = 5602 Handle<DescriptorArray> new_descriptors =
5614 DescriptorArray::CopyUpToAddAttributes( 5603 DescriptorArray::CopyUpToAddAttributes(
5615 handle(old_map->instance_descriptors()), num_descriptors, FROZEN); 5604 handle(old_map->instance_descriptors()), num_descriptors, FROZEN);
5616 Handle<Map> new_map = Map::CopyReplaceDescriptors( 5605 Handle<Map> new_map = Map::CopyReplaceDescriptors(
5617 old_map, new_descriptors, INSERT_TRANSITION, 5606 old_map, new_descriptors, INSERT_TRANSITION,
5618 isolate->factory()->frozen_symbol()); 5607 isolate->factory()->frozen_symbol());
5619 new_map->freeze(); 5608 new_map->freeze();
5620 new_map->set_is_extensible(false); 5609 new_map->set_is_extensible(false);
5621 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 5610 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5622 object->set_map(*new_map); 5611 JSObject::MigrateToMap(object, new_map);
5623 } else { 5612 } else {
5624 // Slow path: need to normalize properties for safety 5613 // Slow path: need to normalize properties for safety
5625 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 5614 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5626 5615
5627 // Create a new map, since other objects with this map may be extensible. 5616 // Create a new map, since other objects with this map may be extensible.
5628 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5617 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5629 Handle<Map> new_map = Map::Copy(handle(object->map())); 5618 Handle<Map> new_map = Map::Copy(handle(object->map()));
5630 new_map->freeze(); 5619 new_map->freeze();
5631 new_map->set_is_extensible(false); 5620 new_map->set_is_extensible(false);
5632 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 5621 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5633 object->set_map(*new_map); 5622 JSObject::MigrateToMap(object, new_map);
5634 5623
5635 // Freeze dictionary-mode properties 5624 // Freeze dictionary-mode properties
5636 FreezeDictionary(object->property_dictionary()); 5625 FreezeDictionary(object->property_dictionary());
5637 } 5626 }
5638 5627
5639 ASSERT(object->map()->has_dictionary_elements()); 5628 ASSERT(object->map()->has_dictionary_elements());
5640 if (!new_element_dictionary.is_null()) { 5629 if (!new_element_dictionary.is_null()) {
5641 object->set_elements(*new_element_dictionary); 5630 object->set_elements(*new_element_dictionary);
5642 } 5631 }
5643 5632
(...skipping 23 matching lines...) Expand all
5667 Handle<Map> new_map; 5656 Handle<Map> new_map;
5668 if (result.IsTransition()) { 5657 if (result.IsTransition()) {
5669 new_map = handle(result.GetTransitionTarget()); 5658 new_map = handle(result.GetTransitionTarget());
5670 ASSERT(new_map->is_observed()); 5659 ASSERT(new_map->is_observed());
5671 } else if (object->map()->CanHaveMoreTransitions()) { 5660 } else if (object->map()->CanHaveMoreTransitions()) {
5672 new_map = Map::CopyForObserved(handle(object->map())); 5661 new_map = Map::CopyForObserved(handle(object->map()));
5673 } else { 5662 } else {
5674 new_map = Map::Copy(handle(object->map())); 5663 new_map = Map::Copy(handle(object->map()));
5675 new_map->set_is_observed(); 5664 new_map->set_is_observed();
5676 } 5665 }
5677 object->set_map(*new_map); 5666 JSObject::MigrateToMap(object, new_map);
5678 } 5667 }
5679 5668
5680 5669
5681 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5670 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5682 Isolate* isolate = object->GetIsolate(); 5671 Isolate* isolate = object->GetIsolate();
5683 CALL_HEAP_FUNCTION(isolate, 5672 CALL_HEAP_FUNCTION(isolate,
5684 isolate->heap()->CopyJSObject(*object), JSObject); 5673 isolate->heap()->CopyJSObject(*object), JSObject);
5685 } 5674 }
5686 5675
5687 5676
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
5788 } 5777 }
5789 } 5778 }
5790 } else { 5779 } else {
5791 Handle<FixedArray> names = 5780 Handle<FixedArray> names =
5792 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); 5781 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
5793 copy->GetLocalPropertyNames(*names, 0); 5782 copy->GetLocalPropertyNames(*names, 0);
5794 for (int i = 0; i < names->length(); i++) { 5783 for (int i = 0; i < names->length(); i++) {
5795 ASSERT(names->get(i)->IsString()); 5784 ASSERT(names->get(i)->IsString());
5796 Handle<String> key_string(String::cast(names->get(i))); 5785 Handle<String> key_string(String::cast(names->get(i)));
5797 PropertyAttributes attributes = 5786 PropertyAttributes attributes =
5798 copy->GetLocalPropertyAttribute(*key_string); 5787 JSReceiver::GetLocalPropertyAttribute(copy, key_string);
5799 // Only deep copy fields from the object literal expression. 5788 // Only deep copy fields from the object literal expression.
5800 // In particular, don't try to copy the length attribute of 5789 // In particular, don't try to copy the length attribute of
5801 // an array. 5790 // an array.
5802 if (attributes != NONE) continue; 5791 if (attributes != NONE) continue;
5803 Handle<Object> value( 5792 Handle<Object> value(
5804 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), 5793 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
5805 isolate); 5794 isolate);
5806 if (value->IsJSObject()) { 5795 if (value->IsJSObject()) {
5807 Handle<JSObject> result = VisitElementOrProperty( 5796 Handle<JSObject> result = VisitElementOrProperty(
5808 copy, Handle<JSObject>::cast(value)); 5797 copy, Handle<JSObject>::cast(value));
5809 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5798 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
5810 if (copying) { 5799 if (copying) {
5811 // Creating object copy for literals. No strict mode needed. 5800 // Creating object copy for literals. No strict mode needed.
5812 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( 5801 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
5813 copy, key_string, result, NONE, kNonStrictMode)); 5802 copy, key_string, result, NONE, SLOPPY));
5814 } 5803 }
5815 } 5804 }
5816 } 5805 }
5817 } 5806 }
5818 5807
5819 // Deep copy local elements. 5808 // Deep copy local elements.
5820 // Pixel elements cannot be created using an object literal. 5809 // Pixel elements cannot be created using an object literal.
5821 ASSERT(!copy->HasExternalArrayElements()); 5810 ASSERT(!copy->HasExternalArrayElements());
5822 switch (kind) { 5811 switch (kind) {
5823 case FAST_SMI_ELEMENTS: 5812 case FAST_SMI_ELEMENTS:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5862 copy, Handle<JSObject>::cast(value)); 5851 copy, Handle<JSObject>::cast(value));
5863 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5852 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
5864 if (copying) { 5853 if (copying) {
5865 element_dictionary->ValueAtPut(i, *result); 5854 element_dictionary->ValueAtPut(i, *result);
5866 } 5855 }
5867 } 5856 }
5868 } 5857 }
5869 } 5858 }
5870 break; 5859 break;
5871 } 5860 }
5872 case NON_STRICT_ARGUMENTS_ELEMENTS: 5861 case SLOPPY_ARGUMENTS_ELEMENTS:
5873 UNIMPLEMENTED(); 5862 UNIMPLEMENTED();
5874 break; 5863 break;
5875 5864
5876 5865
5877 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 5866 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
5878 case EXTERNAL_##TYPE##_ELEMENTS: \ 5867 case EXTERNAL_##TYPE##_ELEMENTS: \
5879 case TYPE##_ELEMENTS: \ 5868 case TYPE##_ELEMENTS: \
5880 5869
5881 TYPED_ARRAYS(TYPED_ARRAY_CASE) 5870 TYPED_ARRAYS(TYPED_ARRAY_CASE)
5882 #undef TYPED_ARRAY_CASE 5871 #undef TYPED_ARRAY_CASE
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5920 // - No prototype has enumerable properties/elements. 5909 // - No prototype has enumerable properties/elements.
5921 bool JSReceiver::IsSimpleEnum() { 5910 bool JSReceiver::IsSimpleEnum() {
5922 Heap* heap = GetHeap(); 5911 Heap* heap = GetHeap();
5923 for (Object* o = this; 5912 for (Object* o = this;
5924 o != heap->null_value(); 5913 o != heap->null_value();
5925 o = JSObject::cast(o)->GetPrototype()) { 5914 o = JSObject::cast(o)->GetPrototype()) {
5926 if (!o->IsJSObject()) return false; 5915 if (!o->IsJSObject()) return false;
5927 JSObject* curr = JSObject::cast(o); 5916 JSObject* curr = JSObject::cast(o);
5928 int enum_length = curr->map()->EnumLength(); 5917 int enum_length = curr->map()->EnumLength();
5929 if (enum_length == kInvalidEnumCacheSentinel) return false; 5918 if (enum_length == kInvalidEnumCacheSentinel) return false;
5919 if (curr->IsAccessCheckNeeded()) return false;
5930 ASSERT(!curr->HasNamedInterceptor()); 5920 ASSERT(!curr->HasNamedInterceptor());
5931 ASSERT(!curr->HasIndexedInterceptor()); 5921 ASSERT(!curr->HasIndexedInterceptor());
5932 ASSERT(!curr->IsAccessCheckNeeded());
5933 if (curr->NumberOfEnumElements() > 0) return false; 5922 if (curr->NumberOfEnumElements() > 0) return false;
5934 if (curr != this && enum_length != 0) return false; 5923 if (curr != this && enum_length != 0) return false;
5935 } 5924 }
5936 return true; 5925 return true;
5937 } 5926 }
5938 5927
5939 5928
5940 static bool FilterKey(Object* key, PropertyAttributes filter) { 5929 static bool FilterKey(Object* key, PropertyAttributes filter) {
5941 if ((filter & SYMBOLIC) && key->IsSymbol()) { 5930 if ((filter & SYMBOLIC) && key->IsSymbol()) {
5942 return true; 5931 return true;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
6123 6112
6124 case DICTIONARY_ELEMENTS: 6113 case DICTIONARY_ELEMENTS:
6125 if (UpdateGetterSetterInDictionary(object->element_dictionary(), 6114 if (UpdateGetterSetterInDictionary(object->element_dictionary(),
6126 index, 6115 index,
6127 *getter, 6116 *getter,
6128 *setter, 6117 *setter,
6129 attributes)) { 6118 attributes)) {
6130 return; 6119 return;
6131 } 6120 }
6132 break; 6121 break;
6133 case NON_STRICT_ARGUMENTS_ELEMENTS: { 6122 case SLOPPY_ARGUMENTS_ELEMENTS: {
6134 // Ascertain whether we have read-only properties or an existing 6123 // Ascertain whether we have read-only properties or an existing
6135 // getter/setter pair in an arguments elements dictionary backing 6124 // getter/setter pair in an arguments elements dictionary backing
6136 // store. 6125 // store.
6137 FixedArray* parameter_map = FixedArray::cast(object->elements()); 6126 FixedArray* parameter_map = FixedArray::cast(object->elements());
6138 uint32_t length = parameter_map->length(); 6127 uint32_t length = parameter_map->length();
6139 Object* probe = 6128 Object* probe =
6140 index < (length - 2) ? parameter_map->get(index + 2) : NULL; 6129 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
6141 if (probe == NULL || probe->IsTheHole()) { 6130 if (probe == NULL || probe->IsTheHole()) {
6142 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 6131 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
6143 if (arguments->IsDictionary()) { 6132 if (arguments->IsDictionary()) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 } 6195 }
6207 6196
6208 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); 6197 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
6209 accessors->SetComponents(*getter, *setter); 6198 accessors->SetComponents(*getter, *setter);
6210 accessors->set_access_flags(access_control); 6199 accessors->set_access_flags(access_control);
6211 6200
6212 SetPropertyCallback(object, name, accessors, attributes); 6201 SetPropertyCallback(object, name, accessors, attributes);
6213 } 6202 }
6214 6203
6215 6204
6216 bool JSObject::CanSetCallback(Name* name) { 6205 bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) {
6217 ASSERT(!IsAccessCheckNeeded() || 6206 Isolate* isolate = object->GetIsolate();
6218 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 6207 ASSERT(!object->IsAccessCheckNeeded() ||
6208 isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET));
6219 6209
6220 // Check if there is an API defined callback object which prohibits 6210 // Check if there is an API defined callback object which prohibits
6221 // callback overwriting in this object or its prototype chain. 6211 // callback overwriting in this object or its prototype chain.
6222 // This mechanism is needed for instance in a browser setting, where 6212 // This mechanism is needed for instance in a browser setting, where
6223 // certain accessors such as window.location should not be allowed 6213 // certain accessors such as window.location should not be allowed
6224 // to be overwritten because allowing overwriting could potentially 6214 // to be overwritten because allowing overwriting could potentially
6225 // cause security problems. 6215 // cause security problems.
6226 LookupResult callback_result(GetIsolate()); 6216 LookupResult callback_result(isolate);
6227 LookupCallbackProperty(name, &callback_result); 6217 object->LookupCallbackProperty(*name, &callback_result);
6228 if (callback_result.IsFound()) { 6218 if (callback_result.IsFound()) {
6229 Object* obj = callback_result.GetCallbackObject(); 6219 Object* callback_obj = callback_result.GetCallbackObject();
6230 if (obj->IsAccessorInfo()) { 6220 if (callback_obj->IsAccessorInfo()) {
6231 return !AccessorInfo::cast(obj)->prohibits_overwriting(); 6221 return !AccessorInfo::cast(callback_obj)->prohibits_overwriting();
6232 } 6222 }
6233 if (obj->IsAccessorPair()) { 6223 if (callback_obj->IsAccessorPair()) {
6234 return !AccessorPair::cast(obj)->prohibits_overwriting(); 6224 return !AccessorPair::cast(callback_obj)->prohibits_overwriting();
6235 } 6225 }
6236 } 6226 }
6237 return true; 6227 return true;
6238 } 6228 }
6239 6229
6240 6230
6241 bool Map::DictionaryElementsInPrototypeChainOnly() { 6231 bool Map::DictionaryElementsInPrototypeChainOnly() {
6242 Heap* heap = GetHeap(); 6232 Heap* heap = GetHeap();
6243 6233
6244 if (IsDictionaryElementsKind(elements_kind())) { 6234 if (IsDictionaryElementsKind(elements_kind())) {
(...skipping 29 matching lines...) Expand all
6274 bool had_dictionary_elements = object->HasDictionaryElements(); 6264 bool had_dictionary_elements = object->HasDictionaryElements();
6275 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6265 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6276 ASSERT(object->HasDictionaryElements() || 6266 ASSERT(object->HasDictionaryElements() ||
6277 object->HasDictionaryArgumentsElements()); 6267 object->HasDictionaryArgumentsElements());
6278 // Update the dictionary with the new CALLBACKS property. 6268 // Update the dictionary with the new CALLBACKS property.
6279 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6269 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6280 details); 6270 details);
6281 dictionary->set_requires_slow_elements(); 6271 dictionary->set_requires_slow_elements();
6282 6272
6283 // Update the dictionary backing store on the object. 6273 // Update the dictionary backing store on the object.
6284 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { 6274 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) {
6285 // Also delete any parameter alias. 6275 // Also delete any parameter alias.
6286 // 6276 //
6287 // TODO(kmillikin): when deleting the last parameter alias we could 6277 // TODO(kmillikin): when deleting the last parameter alias we could
6288 // switch to a direct backing store without the parameter map. This 6278 // switch to a direct backing store without the parameter map. This
6289 // would allow GC of the context. 6279 // would allow GC of the context.
6290 FixedArray* parameter_map = FixedArray::cast(object->elements()); 6280 FixedArray* parameter_map = FixedArray::cast(object->elements());
6291 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { 6281 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
6292 parameter_map->set(index + 2, heap->the_hole_value()); 6282 parameter_map->set(index + 2, heap->the_hole_value());
6293 } 6283 }
6294 parameter_map->set(1, *dictionary); 6284 parameter_map->set(1, *dictionary);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
6331 6321
6332 void JSObject::DefineAccessor(Handle<JSObject> object, 6322 void JSObject::DefineAccessor(Handle<JSObject> object,
6333 Handle<Name> name, 6323 Handle<Name> name,
6334 Handle<Object> getter, 6324 Handle<Object> getter,
6335 Handle<Object> setter, 6325 Handle<Object> setter,
6336 PropertyAttributes attributes, 6326 PropertyAttributes attributes,
6337 v8::AccessControl access_control) { 6327 v8::AccessControl access_control) {
6338 Isolate* isolate = object->GetIsolate(); 6328 Isolate* isolate = object->GetIsolate();
6339 // Check access rights if needed. 6329 // Check access rights if needed.
6340 if (object->IsAccessCheckNeeded() && 6330 if (object->IsAccessCheckNeeded() &&
6341 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 6331 !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
6342 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); 6332 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
6343 return; 6333 return;
6344 } 6334 }
6345 6335
6346 if (object->IsJSGlobalProxy()) { 6336 if (object->IsJSGlobalProxy()) {
6347 Handle<Object> proto(object->GetPrototype(), isolate); 6337 Handle<Object> proto(object->GetPrototype(), isolate);
6348 if (proto->IsNull()) return; 6338 if (proto->IsNull()) return;
6349 ASSERT(proto->IsJSGlobalObject()); 6339 ASSERT(proto->IsJSGlobalObject());
6350 DefineAccessor(Handle<JSObject>::cast(proto), 6340 DefineAccessor(Handle<JSObject>::cast(proto),
6351 name, 6341 name,
6352 getter, 6342 getter,
6353 setter, 6343 setter,
6354 attributes, 6344 attributes,
6355 access_control); 6345 access_control);
6356 return; 6346 return;
6357 } 6347 }
6358 6348
6359 // Make sure that the top context does not change when doing callbacks or 6349 // Make sure that the top context does not change when doing callbacks or
6360 // interceptor calls. 6350 // interceptor calls.
6361 AssertNoContextChange ncc(isolate); 6351 AssertNoContextChange ncc(isolate);
6362 6352
6363 // Try to flatten before operating on the string. 6353 // Try to flatten before operating on the string.
6364 if (name->IsString()) String::cast(*name)->TryFlatten(); 6354 if (name->IsString()) String::cast(*name)->TryFlatten();
6365 6355
6366 if (!object->CanSetCallback(*name)) return; 6356 if (!JSObject::CanSetCallback(object, name)) return;
6367 6357
6368 uint32_t index = 0; 6358 uint32_t index = 0;
6369 bool is_element = name->AsArrayIndex(&index); 6359 bool is_element = name->AsArrayIndex(&index);
6370 6360
6371 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6361 Handle<Object> old_value = isolate->factory()->the_hole_value();
6372 bool is_observed = FLAG_harmony_observation && 6362 bool is_observed = object->map()->is_observed() &&
6373 object->map()->is_observed() &&
6374 *name != isolate->heap()->hidden_string(); 6363 *name != isolate->heap()->hidden_string();
6375 bool preexists = false; 6364 bool preexists = false;
6376 if (is_observed) { 6365 if (is_observed) {
6377 if (is_element) { 6366 if (is_element) {
6378 preexists = HasLocalElement(object, index); 6367 preexists = HasLocalElement(object, index);
6379 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6368 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6380 old_value = Object::GetElement(isolate, object, index); 6369 old_value = Object::GetElement(isolate, object, index);
6381 } 6370 }
6382 } else { 6371 } else {
6383 LookupResult lookup(isolate); 6372 LookupResult lookup(isolate);
(...skipping 13 matching lines...) Expand all
6397 object, name, getter, setter, attributes, access_control); 6386 object, name, getter, setter, attributes, access_control);
6398 } 6387 }
6399 6388
6400 if (is_observed) { 6389 if (is_observed) {
6401 const char* type = preexists ? "reconfigure" : "add"; 6390 const char* type = preexists ? "reconfigure" : "add";
6402 EnqueueChangeRecord(object, type, name, old_value); 6391 EnqueueChangeRecord(object, type, name, old_value);
6403 } 6392 }
6404 } 6393 }
6405 6394
6406 6395
6407 static bool TryAccessorTransition(JSObject* self, 6396 static bool TryAccessorTransition(Handle<JSObject> self,
6408 Map* transitioned_map, 6397 Handle<Map> transitioned_map,
6409 int target_descriptor, 6398 int target_descriptor,
6410 AccessorComponent component, 6399 AccessorComponent component,
6411 Object* accessor, 6400 Handle<Object> accessor,
6412 PropertyAttributes attributes) { 6401 PropertyAttributes attributes) {
6413 DescriptorArray* descs = transitioned_map->instance_descriptors(); 6402 DescriptorArray* descs = transitioned_map->instance_descriptors();
6414 PropertyDetails details = descs->GetDetails(target_descriptor); 6403 PropertyDetails details = descs->GetDetails(target_descriptor);
6415 6404
6416 // If the transition target was not callbacks, fall back to the slow case. 6405 // If the transition target was not callbacks, fall back to the slow case.
6417 if (details.type() != CALLBACKS) return false; 6406 if (details.type() != CALLBACKS) return false;
6418 Object* descriptor = descs->GetCallbacksObject(target_descriptor); 6407 Object* descriptor = descs->GetCallbacksObject(target_descriptor);
6419 if (!descriptor->IsAccessorPair()) return false; 6408 if (!descriptor->IsAccessorPair()) return false;
6420 6409
6421 Object* target_accessor = AccessorPair::cast(descriptor)->get(component); 6410 Object* target_accessor = AccessorPair::cast(descriptor)->get(component);
6422 PropertyAttributes target_attributes = details.attributes(); 6411 PropertyAttributes target_attributes = details.attributes();
6423 6412
6424 // Reuse transition if adding same accessor with same attributes. 6413 // Reuse transition if adding same accessor with same attributes.
6425 if (target_accessor == accessor && target_attributes == attributes) { 6414 if (target_accessor == *accessor && target_attributes == attributes) {
6426 self->set_map(transitioned_map); 6415 JSObject::MigrateToMap(self, transitioned_map);
6427 return true; 6416 return true;
6428 } 6417 }
6429 6418
6430 // If either not the same accessor, or not the same attributes, fall back to 6419 // If either not the same accessor, or not the same attributes, fall back to
6431 // the slow case. 6420 // the slow case.
6432 return false; 6421 return false;
6433 } 6422 }
6434 6423
6435 6424
6436 static MaybeObject* CopyInsertDescriptor(Map* map, 6425 static MaybeObject* CopyInsertDescriptor(Map* map,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
6478 } 6467 }
6479 } else { 6468 } else {
6480 return false; 6469 return false;
6481 } 6470 }
6482 6471
6483 int descriptor_number = result.GetDescriptorIndex(); 6472 int descriptor_number = result.GetDescriptorIndex();
6484 6473
6485 object->map()->LookupTransition(*object, *name, &result); 6474 object->map()->LookupTransition(*object, *name, &result);
6486 6475
6487 if (result.IsFound()) { 6476 if (result.IsFound()) {
6488 Map* target = result.GetTransitionTarget(); 6477 Handle<Map> target(result.GetTransitionTarget());
6489 ASSERT(target->NumberOfOwnDescriptors() == 6478 ASSERT(target->NumberOfOwnDescriptors() ==
6490 object->map()->NumberOfOwnDescriptors()); 6479 object->map()->NumberOfOwnDescriptors());
6491 // This works since descriptors are sorted in order of addition. 6480 // This works since descriptors are sorted in order of addition.
6492 ASSERT(object->map()->instance_descriptors()-> 6481 ASSERT(object->map()->instance_descriptors()->
6493 GetKey(descriptor_number) == *name); 6482 GetKey(descriptor_number) == *name);
6494 return TryAccessorTransition(*object, target, descriptor_number, 6483 return TryAccessorTransition(object, target, descriptor_number,
6495 component, *accessor, attributes); 6484 component, accessor, attributes);
6496 } 6485 }
6497 } else { 6486 } else {
6498 // If not, lookup a transition. 6487 // If not, lookup a transition.
6499 object->map()->LookupTransition(*object, *name, &result); 6488 object->map()->LookupTransition(*object, *name, &result);
6500 6489
6501 // If there is a transition, try to follow it. 6490 // If there is a transition, try to follow it.
6502 if (result.IsFound()) { 6491 if (result.IsFound()) {
6503 Map* target = result.GetTransitionTarget(); 6492 Handle<Map> target(result.GetTransitionTarget());
6504 int descriptor_number = target->LastAdded(); 6493 int descriptor_number = target->LastAdded();
6505 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) 6494 ASSERT(target->instance_descriptors()->GetKey(descriptor_number)
6506 ->Equals(*name)); 6495 ->Equals(*name));
6507 return TryAccessorTransition(*object, target, descriptor_number, 6496 return TryAccessorTransition(object, target, descriptor_number,
6508 component, *accessor, attributes); 6497 component, accessor, attributes);
6509 } 6498 }
6510 } 6499 }
6511 6500
6512 // If there is no transition yet, add a transition to the a new accessor pair 6501 // If there is no transition yet, add a transition to the a new accessor pair
6513 // containing the accessor. Allocate a new pair if there were no source 6502 // containing the accessor. Allocate a new pair if there were no source
6514 // accessors. Otherwise, copy the pair and modify the accessor. 6503 // accessors. Otherwise, copy the pair and modify the accessor.
6515 Handle<AccessorPair> accessors = source_accessors != NULL 6504 Handle<AccessorPair> accessors = source_accessors != NULL
6516 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) 6505 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors))
6517 : isolate->factory()->NewAccessorPair(); 6506 : isolate->factory()->NewAccessorPair();
6518 accessors->set(component, *accessor); 6507 accessors->set(component, *accessor);
6519 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), 6508 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
6520 name, accessors, attributes); 6509 name, accessors, attributes);
6521 object->set_map(*new_map); 6510 JSObject::MigrateToMap(object, new_map);
6522 return true; 6511 return true;
6523 } 6512 }
6524 6513
6525 6514
6526 Handle<Object> JSObject::SetAccessor(Handle<JSObject> object, 6515 Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
6527 Handle<AccessorInfo> info) { 6516 Handle<AccessorInfo> info) {
6528 Isolate* isolate = object->GetIsolate(); 6517 Isolate* isolate = object->GetIsolate();
6529 Factory* factory = isolate->factory(); 6518 Factory* factory = isolate->factory();
6530 Handle<Name> name(Name::cast(info->name())); 6519 Handle<Name> name(Name::cast(info->name()));
6531 6520
6532 // Check access rights if needed. 6521 // Check access rights if needed.
6533 if (object->IsAccessCheckNeeded() && 6522 if (object->IsAccessCheckNeeded() &&
6534 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 6523 !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
6535 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); 6524 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
6536 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 6525 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
6537 return factory->undefined_value(); 6526 return factory->undefined_value();
6538 } 6527 }
6539 6528
6540 if (object->IsJSGlobalProxy()) { 6529 if (object->IsJSGlobalProxy()) {
6541 Handle<Object> proto(object->GetPrototype(), isolate); 6530 Handle<Object> proto(object->GetPrototype(), isolate);
6542 if (proto->IsNull()) return object; 6531 if (proto->IsNull()) return object;
6543 ASSERT(proto->IsJSGlobalObject()); 6532 ASSERT(proto->IsJSGlobalObject());
6544 return SetAccessor(Handle<JSObject>::cast(proto), info); 6533 return SetAccessor(Handle<JSObject>::cast(proto), info);
6545 } 6534 }
6546 6535
6547 // Make sure that the top context does not change when doing callbacks or 6536 // Make sure that the top context does not change when doing callbacks or
6548 // interceptor calls. 6537 // interceptor calls.
6549 AssertNoContextChange ncc(isolate); 6538 AssertNoContextChange ncc(isolate);
6550 6539
6551 // Try to flatten before operating on the string. 6540 // Try to flatten before operating on the string.
6552 if (name->IsString()) FlattenString(Handle<String>::cast(name)); 6541 if (name->IsString()) FlattenString(Handle<String>::cast(name));
6553 6542
6554 if (!object->CanSetCallback(*name)) return factory->undefined_value(); 6543 if (!JSObject::CanSetCallback(object, name)) {
6544 return factory->undefined_value();
6545 }
6555 6546
6556 uint32_t index = 0; 6547 uint32_t index = 0;
6557 bool is_element = name->AsArrayIndex(&index); 6548 bool is_element = name->AsArrayIndex(&index);
6558 6549
6559 if (is_element) { 6550 if (is_element) {
6560 if (object->IsJSArray()) return factory->undefined_value(); 6551 if (object->IsJSArray()) return factory->undefined_value();
6561 6552
6562 // Accessors overwrite previous callbacks (cf. with getters/setters). 6553 // Accessors overwrite previous callbacks (cf. with getters/setters).
6563 switch (object->GetElementsKind()) { 6554 switch (object->GetElementsKind()) {
6564 case FAST_SMI_ELEMENTS: 6555 case FAST_SMI_ELEMENTS:
6565 case FAST_ELEMENTS: 6556 case FAST_ELEMENTS:
6566 case FAST_DOUBLE_ELEMENTS: 6557 case FAST_DOUBLE_ELEMENTS:
6567 case FAST_HOLEY_SMI_ELEMENTS: 6558 case FAST_HOLEY_SMI_ELEMENTS:
6568 case FAST_HOLEY_ELEMENTS: 6559 case FAST_HOLEY_ELEMENTS:
6569 case FAST_HOLEY_DOUBLE_ELEMENTS: 6560 case FAST_HOLEY_DOUBLE_ELEMENTS:
6570 break; 6561 break;
6571 6562
6572 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 6563 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
6573 case EXTERNAL_##TYPE##_ELEMENTS: \ 6564 case EXTERNAL_##TYPE##_ELEMENTS: \
6574 case TYPE##_ELEMENTS: \ 6565 case TYPE##_ELEMENTS: \
6575 6566
6576 TYPED_ARRAYS(TYPED_ARRAY_CASE) 6567 TYPED_ARRAYS(TYPED_ARRAY_CASE)
6577 #undef TYPED_ARRAY_CASE 6568 #undef TYPED_ARRAY_CASE
6578 // Ignore getters and setters on pixel and external array 6569 // Ignore getters and setters on pixel and external array
6579 // elements. 6570 // elements.
6580 return factory->undefined_value(); 6571 return factory->undefined_value();
6581 6572
6582 case DICTIONARY_ELEMENTS: 6573 case DICTIONARY_ELEMENTS:
6583 break; 6574 break;
6584 case NON_STRICT_ARGUMENTS_ELEMENTS: 6575 case SLOPPY_ARGUMENTS_ELEMENTS:
6585 UNIMPLEMENTED(); 6576 UNIMPLEMENTED();
6586 break; 6577 break;
6587 } 6578 }
6588 6579
6589 SetElementCallback(object, index, info, info->property_attributes()); 6580 SetElementCallback(object, index, info, info->property_attributes());
6590 } else { 6581 } else {
6591 // Lookup the name. 6582 // Lookup the name.
6592 LookupResult result(isolate); 6583 LookupResult result(isolate);
6593 object->LocalLookup(*name, &result, true); 6584 object->LocalLookup(*name, &result, true);
6594 // ES5 forbids turning a property into an accessor if it's not 6585 // ES5 forbids turning a property into an accessor if it's not
(...skipping 13 matching lines...) Expand all
6608 Handle<Name> name, 6599 Handle<Name> name,
6609 AccessorComponent component) { 6600 AccessorComponent component) {
6610 Isolate* isolate = object->GetIsolate(); 6601 Isolate* isolate = object->GetIsolate();
6611 6602
6612 // Make sure that the top context does not change when doing callbacks or 6603 // Make sure that the top context does not change when doing callbacks or
6613 // interceptor calls. 6604 // interceptor calls.
6614 AssertNoContextChange ncc(isolate); 6605 AssertNoContextChange ncc(isolate);
6615 6606
6616 // Check access rights if needed. 6607 // Check access rights if needed.
6617 if (object->IsAccessCheckNeeded() && 6608 if (object->IsAccessCheckNeeded() &&
6618 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) { 6609 !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_HAS)) {
6619 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 6610 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
6620 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 6611 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
6621 return isolate->factory()->undefined_value(); 6612 return isolate->factory()->undefined_value();
6622 } 6613 }
6623 6614
6624 // Make the lookup and include prototypes. 6615 // Make the lookup and include prototypes.
6625 uint32_t index = 0; 6616 uint32_t index = 0;
6626 if (name->AsArrayIndex(&index)) { 6617 if (name->AsArrayIndex(&index)) {
6627 for (Handle<Object> obj = object; 6618 for (Handle<Object> obj = object;
6628 !obj->IsNull(); 6619 !obj->IsNull();
6629 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { 6620 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6663 } 6654 }
6664 6655
6665 6656
6666 Object* JSObject::SlowReverseLookup(Object* value) { 6657 Object* JSObject::SlowReverseLookup(Object* value) {
6667 if (HasFastProperties()) { 6658 if (HasFastProperties()) {
6668 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); 6659 int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
6669 DescriptorArray* descs = map()->instance_descriptors(); 6660 DescriptorArray* descs = map()->instance_descriptors();
6670 for (int i = 0; i < number_of_own_descriptors; i++) { 6661 for (int i = 0; i < number_of_own_descriptors; i++) {
6671 if (descs->GetType(i) == FIELD) { 6662 if (descs->GetType(i) == FIELD) {
6672 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); 6663 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
6673 if (FLAG_track_double_fields && 6664 if (descs->GetDetails(i).representation().IsDouble()) {
6674 descs->GetDetails(i).representation().IsDouble()) {
6675 ASSERT(property->IsHeapNumber()); 6665 ASSERT(property->IsHeapNumber());
6676 if (value->IsNumber() && property->Number() == value->Number()) { 6666 if (value->IsNumber() && property->Number() == value->Number()) {
6677 return descs->GetKey(i); 6667 return descs->GetKey(i);
6678 } 6668 }
6679 } else if (property == value) { 6669 } else if (property == value) {
6680 return descs->GetKey(i); 6670 return descs->GetKey(i);
6681 } 6671 }
6682 } else if (descs->GetType(i) == CONSTANT) { 6672 } else if (descs->GetType(i) == CONSTANT) {
6683 if (descs->GetConstant(i) == value) { 6673 if (descs->GetConstant(i) == value) {
6684 return descs->GetKey(i); 6674 return descs->GetKey(i);
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after
8235 } 8225 }
8236 return true; 8226 return true;
8237 } 8227 }
8238 #endif 8228 #endif
8239 8229
8240 8230
8241 static bool IsIdentifier(UnicodeCache* cache, Name* name) { 8231 static bool IsIdentifier(UnicodeCache* cache, Name* name) {
8242 // Checks whether the buffer contains an identifier (no escape). 8232 // Checks whether the buffer contains an identifier (no escape).
8243 if (!name->IsString()) return false; 8233 if (!name->IsString()) return false;
8244 String* string = String::cast(name); 8234 String* string = String::cast(name);
8245 if (string->length() == 0) return false; 8235 if (string->length() == 0) return true;
8246 ConsStringIteratorOp op; 8236 ConsStringIteratorOp op;
8247 StringCharacterStream stream(string, &op); 8237 StringCharacterStream stream(string, &op);
8248 if (!cache->IsIdentifierStart(stream.GetNext())) { 8238 if (!cache->IsIdentifierStart(stream.GetNext())) {
8249 return false; 8239 return false;
8250 } 8240 }
8251 while (stream.HasMore()) { 8241 while (stream.HasMore()) {
8252 if (!cache->IsIdentifierPart(stream.GetNext())) { 8242 if (!cache->IsIdentifierPart(stream.GetNext())) {
8253 return false; 8243 return false;
8254 } 8244 }
8255 } 8245 }
8256 return true; 8246 return true;
8257 } 8247 }
8258 8248
8259 8249
8260 bool Name::IsCacheable(Isolate* isolate) { 8250 bool Name::IsCacheable(Isolate* isolate) {
8261 return IsSymbol() || 8251 return IsSymbol() || IsIdentifier(isolate->unicode_cache(), this);
8262 IsIdentifier(isolate->unicode_cache(), this) ||
8263 this == isolate->heap()->hidden_string();
8264 } 8252 }
8265 8253
8266 8254
8267 bool String::LooksValid() { 8255 bool String::LooksValid() {
8268 if (!GetIsolate()->heap()->Contains(this)) return false; 8256 if (!GetIsolate()->heap()->Contains(this)) return false;
8269 return true; 8257 return true;
8270 } 8258 }
8271 8259
8272 8260
8273 String::FlatContent String::GetFlatContent() { 8261 String::FlatContent String::GetFlatContent() {
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
9459 9447
9460 bool Map::EquivalentToForNormalization(Map* other, 9448 bool Map::EquivalentToForNormalization(Map* other,
9461 PropertyNormalizationMode mode) { 9449 PropertyNormalizationMode mode) {
9462 int properties = mode == CLEAR_INOBJECT_PROPERTIES 9450 int properties = mode == CLEAR_INOBJECT_PROPERTIES
9463 ? 0 : other->inobject_properties(); 9451 ? 0 : other->inobject_properties();
9464 return CheckEquivalent(this, other) && inobject_properties() == properties; 9452 return CheckEquivalent(this, other) && inobject_properties() == properties;
9465 } 9453 }
9466 9454
9467 9455
9468 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) { 9456 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
9469 if (count_of_ptr_entries() > 0) { 9457 for (int i = 0; i < count_of_code_ptr_entries(); i++) {
9470 int first_ptr_offset = OffsetOfElementAt(first_ptr_index()); 9458 int index = first_code_ptr_index() + i;
9471 int last_ptr_offset = 9459 v->VisitCodeEntry(reinterpret_cast<Address>(RawFieldOfElementAt(index)));
9472 OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries() - 1); 9460 }
9473 v->VisitPointers( 9461 for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
9474 HeapObject::RawField(this, first_ptr_offset), 9462 int index = first_heap_ptr_index() + i;
9475 HeapObject::RawField(this, last_ptr_offset)); 9463 v->VisitPointer(RawFieldOfElementAt(index));
9476 } 9464 }
9477 } 9465 }
9478 9466
9479 9467
9480 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 9468 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
9481 // Iterate over all fields in the body but take care in dealing with 9469 // Iterate over all fields in the body but take care in dealing with
9482 // the code entry. 9470 // the code entry.
9483 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 9471 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
9484 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 9472 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
9485 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 9473 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
9633 9621
9634 ASSERT(code_map->get(kNextMapIndex)->IsUndefined()); 9622 ASSERT(code_map->get(kNextMapIndex)->IsUndefined());
9635 set_optimized_code_map(Smi::FromInt(0)); 9623 set_optimized_code_map(Smi::FromInt(0));
9636 } 9624 }
9637 9625
9638 9626
9639 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, 9627 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
9640 const char* reason) { 9628 const char* reason) {
9641 if (optimized_code_map()->IsSmi()) return; 9629 if (optimized_code_map()->IsSmi()) return;
9642 9630
9643 int i;
9644 bool removed_entry = false;
9645 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 9631 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9646 for (i = kEntriesStart; i < code_map->length(); i += kEntryLength) { 9632 int dst = kEntriesStart;
9647 ASSERT(code_map->get(i)->IsNativeContext()); 9633 int length = code_map->length();
9648 if (Code::cast(code_map->get(i + 1)) == optimized_code) { 9634 for (int src = kEntriesStart; src < length; src += kEntryLength) {
9635 ASSERT(code_map->get(src)->IsNativeContext());
9636 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) {
9637 // Evict the src entry by not copying it to the dst entry.
9649 if (FLAG_trace_opt) { 9638 if (FLAG_trace_opt) {
9650 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 9639 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
9651 ShortPrint(); 9640 ShortPrint();
9652 PrintF("]\n"); 9641 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
9642 if (osr.IsNone()) {
9643 PrintF("]\n");
9644 } else {
9645 PrintF(" (osr ast id %d)]\n", osr.ToInt());
9646 }
9653 } 9647 }
9654 removed_entry = true; 9648 } else {
9655 break; 9649 // Keep the src entry by copying it to the dst entry.
9650 if (dst != src) {
9651 code_map->set(dst + kContextOffset,
9652 code_map->get(src + kContextOffset));
9653 code_map->set(dst + kCachedCodeOffset,
9654 code_map->get(src + kCachedCodeOffset));
9655 code_map->set(dst + kLiteralsOffset,
9656 code_map->get(src + kLiteralsOffset));
9657 code_map->set(dst + kOsrAstIdOffset,
9658 code_map->get(src + kOsrAstIdOffset));
9659 }
9660 dst += kEntryLength;
9656 } 9661 }
9657 } 9662 }
9658 while (i < (code_map->length() - kEntryLength)) { 9663 if (dst != length) {
9659 code_map->set(i + kContextOffset,
9660 code_map->get(i + kContextOffset + kEntryLength));
9661 code_map->set(i + kCachedCodeOffset,
9662 code_map->get(i + kCachedCodeOffset + kEntryLength));
9663 code_map->set(i + kLiteralsOffset,
9664 code_map->get(i + kLiteralsOffset + kEntryLength));
9665 code_map->set(i + kOsrAstIdOffset,
9666 code_map->get(i + kOsrAstIdOffset + kEntryLength));
9667 i += kEntryLength;
9668 }
9669 if (removed_entry) {
9670 // Always trim even when array is cleared because of heap verifier. 9664 // Always trim even when array is cleared because of heap verifier.
9671 RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, kEntryLength); 9665 RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, length - dst);
9672 if (code_map->length() == kEntriesStart) { 9666 if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap();
9673 ClearOptimizedCodeMap();
9674 }
9675 } 9667 }
9676 } 9668 }
9677 9669
9678 9670
9679 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { 9671 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
9680 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 9672 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9681 ASSERT(shrink_by % kEntryLength == 0); 9673 ASSERT(shrink_by % kEntryLength == 0);
9682 ASSERT(shrink_by <= code_map->length() - kEntriesStart); 9674 ASSERT(shrink_by <= code_map->length() - kEntriesStart);
9683 // Always trim even when array is cleared because of heap verifier. 9675 // Always trim even when array is cleared because of heap verifier.
9684 RightTrimFixedArray<FROM_GC>(GetHeap(), code_map, shrink_by); 9676 RightTrimFixedArray<FROM_GC>(GetHeap(), code_map, shrink_by);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
9792 // If the value is not a JSReceiver, store the value in the map's 9784 // If the value is not a JSReceiver, store the value in the map's
9793 // constructor field so it can be accessed. Also, set the prototype 9785 // constructor field so it can be accessed. Also, set the prototype
9794 // used for constructing objects to the original object prototype. 9786 // used for constructing objects to the original object prototype.
9795 // See ECMA-262 13.2.2. 9787 // See ECMA-262 13.2.2.
9796 if (!value->IsJSReceiver()) { 9788 if (!value->IsJSReceiver()) {
9797 // Copy the map so this does not affect unrelated functions. 9789 // Copy the map so this does not affect unrelated functions.
9798 // Remove map transitions because they point to maps with a 9790 // Remove map transitions because they point to maps with a
9799 // different prototype. 9791 // different prototype.
9800 Handle<Map> new_map = Map::Copy(handle(function->map())); 9792 Handle<Map> new_map = Map::Copy(handle(function->map()));
9801 9793
9802 function->set_map(*new_map); 9794 JSObject::MigrateToMap(function, new_map);
9803 new_map->set_constructor(*value); 9795 new_map->set_constructor(*value);
9804 new_map->set_non_instance_prototype(true); 9796 new_map->set_non_instance_prototype(true);
9805 Isolate* isolate = new_map->GetIsolate(); 9797 Isolate* isolate = new_map->GetIsolate();
9806 construct_prototype = handle( 9798 construct_prototype = handle(
9807 isolate->context()->native_context()->initial_object_prototype(), 9799 isolate->context()->native_context()->initial_object_prototype(),
9808 isolate); 9800 isolate);
9809 } else { 9801 } else {
9810 function->map()->set_non_instance_prototype(false); 9802 function->map()->set_non_instance_prototype(false);
9811 } 9803 }
9812 9804
9813 return SetInstancePrototype(function, construct_prototype); 9805 return SetInstancePrototype(function, construct_prototype);
9814 } 9806 }
9815 9807
9816 9808
9817 void JSFunction::RemovePrototype() { 9809 void JSFunction::RemovePrototype() {
9818 Context* native_context = context()->native_context(); 9810 Context* native_context = context()->native_context();
9819 Map* no_prototype_map = shared()->is_classic_mode() 9811 Map* no_prototype_map = shared()->strict_mode() == SLOPPY
9820 ? native_context->function_without_prototype_map() 9812 ? native_context->sloppy_function_without_prototype_map()
9821 : native_context->strict_mode_function_without_prototype_map(); 9813 : native_context->strict_function_without_prototype_map();
9822 9814
9823 if (map() == no_prototype_map) return; 9815 if (map() == no_prototype_map) return;
9824 9816
9825 ASSERT(map() == (shared()->is_classic_mode() 9817 ASSERT(map() == (shared()->strict_mode() == SLOPPY
9826 ? native_context->function_map() 9818 ? native_context->sloppy_function_map()
9827 : native_context->strict_mode_function_map())); 9819 : native_context->strict_function_map()));
9828 9820
9829 set_map(no_prototype_map); 9821 set_map(no_prototype_map);
9830 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); 9822 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
9831 } 9823 }
9832 9824
9833 9825
9834 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { 9826 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
9835 if (function->has_initial_map()) return; 9827 if (function->has_initial_map()) return;
9836 Isolate* isolate = function->GetIsolate(); 9828 Isolate* isolate = function->GetIsolate();
9837 9829
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
10635 10627
10636 void Code::ClearInlineCaches(Code::Kind* kind) { 10628 void Code::ClearInlineCaches(Code::Kind* kind) {
10637 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 10629 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
10638 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | 10630 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
10639 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 10631 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
10640 for (RelocIterator it(this, mask); !it.done(); it.next()) { 10632 for (RelocIterator it(this, mask); !it.done(); it.next()) {
10641 RelocInfo* info = it.rinfo(); 10633 RelocInfo* info = it.rinfo();
10642 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); 10634 Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
10643 if (target->is_inline_cache_stub()) { 10635 if (target->is_inline_cache_stub()) {
10644 if (kind == NULL || *kind == target->kind()) { 10636 if (kind == NULL || *kind == target->kind()) {
10645 IC::Clear(this->GetIsolate(), info->pc()); 10637 IC::Clear(this->GetIsolate(), info->pc(),
10638 info->host()->constant_pool());
10646 } 10639 }
10647 } 10640 }
10648 } 10641 }
10649 } 10642 }
10650 10643
10651 10644
10652 void Code::ClearTypeFeedbackInfo(Heap* heap) { 10645 void SharedFunctionInfo::ClearTypeFeedbackInfo(Heap* heap) {
10653 if (kind() != FUNCTION) return; 10646 FixedArray* vector = feedback_vector();
10654 Object* raw_info = type_feedback_info(); 10647 for (int i = 0; i < vector->length(); i++) {
10655 if (raw_info->IsTypeFeedbackInfo()) { 10648 Object* obj = vector->get(i);
10656 FixedArray* feedback_vector = 10649 if (!obj->IsAllocationSite()) {
10657 TypeFeedbackInfo::cast(raw_info)->feedback_vector(); 10650 // The assert verifies we can skip the write barrier.
10658 for (int i = 0; i < feedback_vector->length(); i++) { 10651 ASSERT(heap->uninitialized_symbol() ==
10659 Object* obj = feedback_vector->get(i); 10652 TypeFeedbackInfo::RawUninitializedSentinel(heap));
10660 if (!obj->IsAllocationSite()) { 10653 vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap),
10661 // TODO(mvstanton): Can't I avoid a write barrier for this sentinel? 10654 SKIP_WRITE_BARRIER);
10662 feedback_vector->set(i,
10663 TypeFeedbackInfo::RawUninitializedSentinel(heap));
10664 }
10665 } 10655 }
10666 } 10656 }
10667 } 10657 }
10668 10658
10669 10659
10670 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { 10660 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) {
10671 DisallowHeapAllocation no_gc; 10661 DisallowHeapAllocation no_gc;
10672 ASSERT(kind() == FUNCTION); 10662 ASSERT(kind() == FUNCTION);
10673 BackEdgeTable back_edges(this, &no_gc); 10663 BackEdgeTable back_edges(this, &no_gc);
10674 for (uint32_t i = 0; i < back_edges.length(); i++) { 10664 for (uint32_t i = 0; i < back_edges.length(); i++) {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
11079 return NULL; 11069 return NULL;
11080 } 11070 }
11081 11071
11082 11072
11083 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { 11073 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
11084 PrintF(out, "extra_ic_state = "); 11074 PrintF(out, "extra_ic_state = ");
11085 const char* name = NULL; 11075 const char* name = NULL;
11086 switch (kind) { 11076 switch (kind) {
11087 case STORE_IC: 11077 case STORE_IC:
11088 case KEYED_STORE_IC: 11078 case KEYED_STORE_IC:
11089 if (extra == kStrictMode) { 11079 if (extra == STRICT) name = "STRICT";
11090 name = "STRICT";
11091 }
11092 break; 11080 break;
11093 default: 11081 default:
11094 break; 11082 break;
11095 } 11083 }
11096 if (name != NULL) { 11084 if (name != NULL) {
11097 PrintF(out, "%s\n", name); 11085 PrintF(out, "%s\n", name);
11098 } else { 11086 } else {
11099 PrintF(out, "%d\n", extra); 11087 PrintF(out, "%d\n", extra);
11100 } 11088 }
11101 } 11089 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
11248 } else { 11236 } else {
11249 new_elements_kind = FAST_ELEMENTS; 11237 new_elements_kind = FAST_ELEMENTS;
11250 } 11238 }
11251 } 11239 }
11252 FixedArrayBase* old_elements = elements(); 11240 FixedArrayBase* old_elements = elements();
11253 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); 11241 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind);
11254 MaybeObject* maybe_obj = 11242 MaybeObject* maybe_obj =
11255 accessor->CopyElements(this, new_elements, elements_kind); 11243 accessor->CopyElements(this, new_elements, elements_kind);
11256 if (maybe_obj->IsFailure()) return maybe_obj; 11244 if (maybe_obj->IsFailure()) return maybe_obj;
11257 11245
11258 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { 11246 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
11259 Map* new_map = map(); 11247 Map* new_map = map();
11260 if (new_elements_kind != elements_kind) { 11248 if (new_elements_kind != elements_kind) {
11261 MaybeObject* maybe = 11249 MaybeObject* maybe =
11262 GetElementsTransitionMap(GetIsolate(), new_elements_kind); 11250 GetElementsTransitionMap(GetIsolate(), new_elements_kind);
11263 if (!maybe->To(&new_map)) return maybe; 11251 if (!maybe->To(&new_map)) return maybe;
11264 } 11252 }
11265 ValidateElements(); 11253 ValidateElements();
11266 set_map_and_elements(new_map, new_elements); 11254 set_map_and_elements(new_map, new_elements);
11267 11255
11268 // Transition through the allocation site as well if present. 11256 // Transition through the allocation site as well if present.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
11320 GetElementsTransitionMap(heap->isolate(), new_elements_kind); 11308 GetElementsTransitionMap(heap->isolate(), new_elements_kind);
11321 if (!maybe_obj->To(&new_map)) return maybe_obj; 11309 if (!maybe_obj->To(&new_map)) return maybe_obj;
11322 } 11310 }
11323 11311
11324 FixedArrayBase* old_elements = elements(); 11312 FixedArrayBase* old_elements = elements();
11325 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); 11313 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS);
11326 { MaybeObject* maybe_obj = 11314 { MaybeObject* maybe_obj =
11327 accessor->CopyElements(this, elems, elements_kind); 11315 accessor->CopyElements(this, elems, elements_kind);
11328 if (maybe_obj->IsFailure()) return maybe_obj; 11316 if (maybe_obj->IsFailure()) return maybe_obj;
11329 } 11317 }
11330 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { 11318 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
11331 ValidateElements(); 11319 ValidateElements();
11332 set_map_and_elements(new_map, elems); 11320 set_map_and_elements(new_map, elems);
11333 } else { 11321 } else {
11334 FixedArray* parameter_map = FixedArray::cast(old_elements); 11322 FixedArray* parameter_map = FixedArray::cast(old_elements);
11335 parameter_map->set(1, elems); 11323 parameter_map->set(1, elems);
11336 } 11324 }
11337 11325
11338 if (FLAG_trace_elements_transitions) { 11326 if (FLAG_trace_elements_transitions) {
11339 PrintElementsTransition(stdout, elements_kind, old_elements, 11327 PrintElementsTransition(stdout, elements_kind, old_elements,
11340 GetElementsKind(), elems); 11328 GetElementsKind(), elems);
(...skipping 21 matching lines...) Expand all
11362 11350
11363 11351
11364 // Returns false if the passed-in index is marked non-configurable, 11352 // Returns false if the passed-in index is marked non-configurable,
11365 // which will cause the ES5 truncation operation to halt, and thus 11353 // which will cause the ES5 truncation operation to halt, and thus
11366 // no further old values need be collected. 11354 // no further old values need be collected.
11367 static bool GetOldValue(Isolate* isolate, 11355 static bool GetOldValue(Isolate* isolate,
11368 Handle<JSObject> object, 11356 Handle<JSObject> object,
11369 uint32_t index, 11357 uint32_t index,
11370 List<Handle<Object> >* old_values, 11358 List<Handle<Object> >* old_values,
11371 List<uint32_t>* indices) { 11359 List<uint32_t>* indices) {
11372 PropertyAttributes attributes = object->GetLocalElementAttribute(index); 11360 PropertyAttributes attributes =
11361 JSReceiver::GetLocalElementAttribute(object, index);
11373 ASSERT(attributes != ABSENT); 11362 ASSERT(attributes != ABSENT);
11374 if (attributes == DONT_DELETE) return false; 11363 if (attributes == DONT_DELETE) return false;
11375 old_values->Add(object->GetLocalElementAccessorPair(index) == NULL 11364 old_values->Add(object->GetLocalElementAccessorPair(index) == NULL
11376 ? Object::GetElement(isolate, object, index) 11365 ? Object::GetElement(isolate, object, index)
11377 : Handle<Object>::cast(isolate->factory()->the_hole_value())); 11366 : Handle<Object>::cast(isolate->factory()->the_hole_value()));
11378 indices->Add(index); 11367 indices->Add(index);
11379 return true; 11368 return true;
11380 } 11369 }
11381 11370
11382 static void EnqueueSpliceRecord(Handle<JSArray> object, 11371 static void EnqueueSpliceRecord(Handle<JSArray> object,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
11425 Handle<JSFunction>(isolate->observers_end_perform_splice()), 11414 Handle<JSFunction>(isolate->observers_end_perform_splice()),
11426 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, 11415 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
11427 &threw); 11416 &threw);
11428 ASSERT(!threw); 11417 ASSERT(!threw);
11429 } 11418 }
11430 11419
11431 11420
11432 MaybeObject* JSArray::SetElementsLength(Object* len) { 11421 MaybeObject* JSArray::SetElementsLength(Object* len) {
11433 // We should never end in here with a pixel or external array. 11422 // We should never end in here with a pixel or external array.
11434 ASSERT(AllowsSetElementsLength()); 11423 ASSERT(AllowsSetElementsLength());
11435 if (!(FLAG_harmony_observation && map()->is_observed())) 11424 if (!map()->is_observed())
11436 return GetElementsAccessor()->SetLength(this, len); 11425 return GetElementsAccessor()->SetLength(this, len);
11437 11426
11438 Isolate* isolate = GetIsolate(); 11427 Isolate* isolate = GetIsolate();
11439 HandleScope scope(isolate); 11428 HandleScope scope(isolate);
11440 Handle<JSArray> self(this); 11429 Handle<JSArray> self(this);
11441 List<uint32_t> indices; 11430 List<uint32_t> indices;
11442 List<Handle<Object> > old_values; 11431 List<Handle<Object> > old_values;
11443 Handle<Object> old_length_handle(self->length(), isolate); 11432 Handle<Object> old_length_handle(self->length(), isolate);
11444 Handle<Object> new_length_handle(len, isolate); 11433 Handle<Object> new_length_handle(len, isolate);
11445 uint32_t old_length = 0; 11434 uint32_t old_length = 0;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
11491 11480
11492 EndPerformSplice(self); 11481 EndPerformSplice(self);
11493 11482
11494 uint32_t index = Min(old_length, new_length); 11483 uint32_t index = Min(old_length, new_length);
11495 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; 11484 uint32_t add_count = new_length > old_length ? new_length - old_length : 0;
11496 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; 11485 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0;
11497 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); 11486 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
11498 if (delete_count > 0) { 11487 if (delete_count > 0) {
11499 for (int i = indices.length() - 1; i >= 0; i--) { 11488 for (int i = indices.length() - 1; i >= 0; i--) {
11500 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, 11489 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
11501 kNonStrictMode); 11490 SLOPPY);
11502 } 11491 }
11503 11492
11504 SetProperty(deleted, isolate->factory()->length_string(), 11493 SetProperty(deleted, isolate->factory()->length_string(),
11505 isolate->factory()->NewNumberFromUint(delete_count), 11494 isolate->factory()->NewNumberFromUint(delete_count),
11506 NONE, kNonStrictMode); 11495 NONE, SLOPPY);
11507 } 11496 }
11508 11497
11509 EnqueueSpliceRecord(self, index, deleted, add_count); 11498 EnqueueSpliceRecord(self, index, deleted, add_count);
11510 11499
11511 return *hresult; 11500 return *hresult;
11512 } 11501 }
11513 11502
11514 11503
11515 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, 11504 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map,
11516 Handle<Object> prototype) { 11505 Handle<Object> prototype) {
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
11869 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); 11858 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
11870 } 11859 }
11871 11860
11872 Handle<Map> new_map = Map::GetPrototypeTransition(map, value); 11861 Handle<Map> new_map = Map::GetPrototypeTransition(map, value);
11873 if (new_map.is_null()) { 11862 if (new_map.is_null()) {
11874 new_map = Map::Copy(map); 11863 new_map = Map::Copy(map);
11875 Map::PutPrototypeTransition(map, value, new_map); 11864 Map::PutPrototypeTransition(map, value, new_map);
11876 new_map->set_prototype(*value); 11865 new_map->set_prototype(*value);
11877 } 11866 }
11878 ASSERT(new_map->prototype() == *value); 11867 ASSERT(new_map->prototype() == *value);
11879 real_receiver->set_map(*new_map); 11868 JSObject::MigrateToMap(real_receiver, new_map);
11880 11869
11881 if (!dictionary_elements_in_chain && 11870 if (!dictionary_elements_in_chain &&
11882 new_map->DictionaryElementsInPrototypeChainOnly()) { 11871 new_map->DictionaryElementsInPrototypeChainOnly()) {
11883 // If the prototype chain didn't previously have element callbacks, then 11872 // If the prototype chain didn't previously have element callbacks, then
11884 // KeyedStoreICs need to be cleared to ensure any that involve this 11873 // KeyedStoreICs need to be cleared to ensure any that involve this
11885 // map go generic. 11874 // map go generic.
11886 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); 11875 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
11887 } 11876 }
11888 11877
11889 heap->ClearInstanceofCache(); 11878 heap->ClearInstanceofCache();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
11935 11924
11936 return GetElementsAccessor()->GetAccessorPair(this, this, index); 11925 return GetElementsAccessor()->GetAccessorPair(this, this, index);
11937 } 11926 }
11938 11927
11939 11928
11940 Handle<Object> JSObject::SetElementWithInterceptor( 11929 Handle<Object> JSObject::SetElementWithInterceptor(
11941 Handle<JSObject> object, 11930 Handle<JSObject> object,
11942 uint32_t index, 11931 uint32_t index,
11943 Handle<Object> value, 11932 Handle<Object> value,
11944 PropertyAttributes attributes, 11933 PropertyAttributes attributes,
11945 StrictModeFlag strict_mode, 11934 StrictMode strict_mode,
11946 bool check_prototype, 11935 bool check_prototype,
11947 SetPropertyMode set_mode) { 11936 SetPropertyMode set_mode) {
11948 Isolate* isolate = object->GetIsolate(); 11937 Isolate* isolate = object->GetIsolate();
11949 11938
11950 // Make sure that the top context does not change when doing 11939 // Make sure that the top context does not change when doing
11951 // callbacks or interceptor calls. 11940 // callbacks or interceptor calls.
11952 AssertNoContextChange ncc(isolate); 11941 AssertNoContextChange ncc(isolate);
11953 11942
11954 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); 11943 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
11955 if (!interceptor->setter()->IsUndefined()) { 11944 if (!interceptor->setter()->IsUndefined()) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
12023 UNREACHABLE(); 12012 UNREACHABLE();
12024 return NULL; 12013 return NULL;
12025 } 12014 }
12026 12015
12027 12016
12028 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, 12017 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
12029 Handle<Object> structure, 12018 Handle<Object> structure,
12030 uint32_t index, 12019 uint32_t index,
12031 Handle<Object> value, 12020 Handle<Object> value,
12032 Handle<JSObject> holder, 12021 Handle<JSObject> holder,
12033 StrictModeFlag strict_mode) { 12022 StrictMode strict_mode) {
12034 Isolate* isolate = object->GetIsolate(); 12023 Isolate* isolate = object->GetIsolate();
12035 12024
12036 // We should never get here to initialize a const with the hole 12025 // We should never get here to initialize a const with the hole
12037 // value since a const declaration would conflict with the setter. 12026 // value since a const declaration would conflict with the setter.
12038 ASSERT(!value->IsTheHole()); 12027 ASSERT(!value->IsTheHole());
12039 12028
12040 // To accommodate both the old and the new api we switch on the 12029 // To accommodate both the old and the new api we switch on the
12041 // data structure used to store the callbacks. Eventually foreign 12030 // data structure used to store the callbacks. Eventually foreign
12042 // callbacks should be phased out. 12031 // callbacks should be phased out.
12043 ASSERT(!structure->IsForeign()); 12032 ASSERT(!structure->IsForeign());
(...skipping 18 matching lines...) Expand all
12062 return value; 12051 return value;
12063 } 12052 }
12064 12053
12065 if (structure->IsAccessorPair()) { 12054 if (structure->IsAccessorPair()) {
12066 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 12055 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
12067 if (setter->IsSpecFunction()) { 12056 if (setter->IsSpecFunction()) {
12068 // TODO(rossberg): nicer would be to cast to some JSCallable here... 12057 // TODO(rossberg): nicer would be to cast to some JSCallable here...
12069 return SetPropertyWithDefinedSetter( 12058 return SetPropertyWithDefinedSetter(
12070 object, Handle<JSReceiver>::cast(setter), value); 12059 object, Handle<JSReceiver>::cast(setter), value);
12071 } else { 12060 } else {
12072 if (strict_mode == kNonStrictMode) { 12061 if (strict_mode == SLOPPY) return value;
12073 return value;
12074 }
12075 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); 12062 Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
12076 Handle<Object> args[2] = { key, holder }; 12063 Handle<Object> args[2] = { key, holder };
12077 Handle<Object> error = isolate->factory()->NewTypeError( 12064 Handle<Object> error = isolate->factory()->NewTypeError(
12078 "no_setter_in_callback", HandleVector(args, 2)); 12065 "no_setter_in_callback", HandleVector(args, 2));
12079 isolate->Throw(*error); 12066 isolate->Throw(*error);
12080 return Handle<Object>(); 12067 return Handle<Object>();
12081 } 12068 }
12082 } 12069 }
12083 12070
12084 // TODO(dcarney): Handle correctly. 12071 // TODO(dcarney): Handle correctly.
12085 if (structure->IsDeclaredAccessorInfo()) return value; 12072 if (structure->IsDeclaredAccessorInfo()) return value;
12086 12073
12087 UNREACHABLE(); 12074 UNREACHABLE();
12088 return Handle<Object>(); 12075 return Handle<Object>();
12089 } 12076 }
12090 12077
12091 12078
12092 bool JSObject::HasFastArgumentsElements() { 12079 bool JSObject::HasFastArgumentsElements() {
12093 Heap* heap = GetHeap(); 12080 Heap* heap = GetHeap();
12094 if (!elements()->IsFixedArray()) return false; 12081 if (!elements()->IsFixedArray()) return false;
12095 FixedArray* elements = FixedArray::cast(this->elements()); 12082 FixedArray* elements = FixedArray::cast(this->elements());
12096 if (elements->map() != heap->non_strict_arguments_elements_map()) { 12083 if (elements->map() != heap->sloppy_arguments_elements_map()) {
12097 return false; 12084 return false;
12098 } 12085 }
12099 FixedArray* arguments = FixedArray::cast(elements->get(1)); 12086 FixedArray* arguments = FixedArray::cast(elements->get(1));
12100 return !arguments->IsDictionary(); 12087 return !arguments->IsDictionary();
12101 } 12088 }
12102 12089
12103 12090
12104 bool JSObject::HasDictionaryArgumentsElements() { 12091 bool JSObject::HasDictionaryArgumentsElements() {
12105 Heap* heap = GetHeap(); 12092 Heap* heap = GetHeap();
12106 if (!elements()->IsFixedArray()) return false; 12093 if (!elements()->IsFixedArray()) return false;
12107 FixedArray* elements = FixedArray::cast(this->elements()); 12094 FixedArray* elements = FixedArray::cast(this->elements());
12108 if (elements->map() != heap->non_strict_arguments_elements_map()) { 12095 if (elements->map() != heap->sloppy_arguments_elements_map()) {
12109 return false; 12096 return false;
12110 } 12097 }
12111 FixedArray* arguments = FixedArray::cast(elements->get(1)); 12098 FixedArray* arguments = FixedArray::cast(elements->get(1));
12112 return arguments->IsDictionary(); 12099 return arguments->IsDictionary();
12113 } 12100 }
12114 12101
12115 12102
12116 // Adding n elements in fast case is O(n*n). 12103 // Adding n elements in fast case is O(n*n).
12117 // Note: revisit design to have dual undefined values to capture absent 12104 // Note: revisit design to have dual undefined values to capture absent
12118 // elements. 12105 // elements.
12119 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, 12106 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
12120 uint32_t index, 12107 uint32_t index,
12121 Handle<Object> value, 12108 Handle<Object> value,
12122 StrictModeFlag strict_mode, 12109 StrictMode strict_mode,
12123 bool check_prototype) { 12110 bool check_prototype) {
12124 ASSERT(object->HasFastSmiOrObjectElements() || 12111 ASSERT(object->HasFastSmiOrObjectElements() ||
12125 object->HasFastArgumentsElements()); 12112 object->HasFastArgumentsElements());
12126 12113
12127 Isolate* isolate = object->GetIsolate(); 12114 Isolate* isolate = object->GetIsolate();
12128 12115
12129 // Array optimizations rely on the prototype lookups of Array objects always 12116 // Array optimizations rely on the prototype lookups of Array objects always
12130 // returning undefined. If there is a store to the initial prototype object, 12117 // returning undefined. If there is a store to the initial prototype object,
12131 // make sure all of these optimizations are invalidated. 12118 // make sure all of these optimizations are invalidated.
12132 if (isolate->is_initial_object_prototype(*object) || 12119 if (isolate->is_initial_object_prototype(*object) ||
12133 isolate->is_initial_array_prototype(*object)) { 12120 isolate->is_initial_array_prototype(*object)) {
12134 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, 12121 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate,
12135 DependentCode::kElementsCantBeAddedGroup); 12122 DependentCode::kElementsCantBeAddedGroup);
12136 } 12123 }
12137 12124
12138 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); 12125 Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
12139 if (backing_store->map() == 12126 if (backing_store->map() ==
12140 isolate->heap()->non_strict_arguments_elements_map()) { 12127 isolate->heap()->sloppy_arguments_elements_map()) {
12141 backing_store = handle(FixedArray::cast(backing_store->get(1))); 12128 backing_store = handle(FixedArray::cast(backing_store->get(1)));
12142 } else { 12129 } else {
12143 backing_store = EnsureWritableFastElements(object); 12130 backing_store = EnsureWritableFastElements(object);
12144 } 12131 }
12145 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); 12132 uint32_t capacity = static_cast<uint32_t>(backing_store->length());
12146 12133
12147 if (check_prototype && 12134 if (check_prototype &&
12148 (index >= capacity || backing_store->get(index)->IsTheHole())) { 12135 (index >= capacity || backing_store->get(index)->IsTheHole())) {
12149 bool found; 12136 bool found;
12150 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( 12137 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
12210 return value; 12197 return value;
12211 } 12198 }
12212 // Change elements kind from Smi-only to generic FAST if necessary. 12199 // Change elements kind from Smi-only to generic FAST if necessary.
12213 if (object->HasFastSmiElements() && !value->IsSmi()) { 12200 if (object->HasFastSmiElements() && !value->IsSmi()) {
12214 ElementsKind kind = object->HasFastHoleyElements() 12201 ElementsKind kind = object->HasFastHoleyElements()
12215 ? FAST_HOLEY_ELEMENTS 12202 ? FAST_HOLEY_ELEMENTS
12216 : FAST_ELEMENTS; 12203 : FAST_ELEMENTS;
12217 12204
12218 UpdateAllocationSite(object, kind); 12205 UpdateAllocationSite(object, kind);
12219 Handle<Map> new_map = GetElementsTransitionMap(object, kind); 12206 Handle<Map> new_map = GetElementsTransitionMap(object, kind);
12220 object->set_map(*new_map); 12207 JSObject::MigrateToMap(object, new_map);
12221 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); 12208 ASSERT(IsFastObjectElementsKind(object->GetElementsKind()));
12222 } 12209 }
12223 // Increase backing store capacity if that's been decided previously. 12210 // Increase backing store capacity if that's been decided previously.
12224 if (new_capacity != capacity) { 12211 if (new_capacity != capacity) {
12225 SetFastElementsCapacitySmiMode smi_mode = 12212 SetFastElementsCapacitySmiMode smi_mode =
12226 value->IsSmi() && object->HasFastSmiElements() 12213 value->IsSmi() && object->HasFastSmiElements()
12227 ? kAllowSmiElements 12214 ? kAllowSmiElements
12228 : kDontAllowSmiElements; 12215 : kDontAllowSmiElements;
12229 Handle<FixedArray> new_elements = 12216 Handle<FixedArray> new_elements =
12230 SetFastElementsCapacityAndLength(object, new_capacity, array_length, 12217 SetFastElementsCapacityAndLength(object, new_capacity, array_length,
(...skipping 10 matching lines...) Expand all
12241 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); 12228 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
12242 } 12229 }
12243 return value; 12230 return value;
12244 } 12231 }
12245 12232
12246 12233
12247 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, 12234 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
12248 uint32_t index, 12235 uint32_t index,
12249 Handle<Object> value, 12236 Handle<Object> value,
12250 PropertyAttributes attributes, 12237 PropertyAttributes attributes,
12251 StrictModeFlag strict_mode, 12238 StrictMode strict_mode,
12252 bool check_prototype, 12239 bool check_prototype,
12253 SetPropertyMode set_mode) { 12240 SetPropertyMode set_mode) {
12254 ASSERT(object->HasDictionaryElements() || 12241 ASSERT(object->HasDictionaryElements() ||
12255 object->HasDictionaryArgumentsElements()); 12242 object->HasDictionaryArgumentsElements());
12256 Isolate* isolate = object->GetIsolate(); 12243 Isolate* isolate = object->GetIsolate();
12257 12244
12258 // Insert element in the dictionary. 12245 // Insert element in the dictionary.
12259 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 12246 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
12260 bool is_arguments = 12247 bool is_arguments =
12261 (elements->map() == isolate->heap()->non_strict_arguments_elements_map()); 12248 (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
12262 Handle<SeededNumberDictionary> dictionary(is_arguments 12249 Handle<SeededNumberDictionary> dictionary(is_arguments
12263 ? SeededNumberDictionary::cast(elements->get(1)) 12250 ? SeededNumberDictionary::cast(elements->get(1))
12264 : SeededNumberDictionary::cast(*elements)); 12251 : SeededNumberDictionary::cast(*elements));
12265 12252
12266 int entry = dictionary->FindEntry(index); 12253 int entry = dictionary->FindEntry(index);
12267 if (entry != SeededNumberDictionary::kNotFound) { 12254 if (entry != SeededNumberDictionary::kNotFound) {
12268 Handle<Object> element(dictionary->ValueAt(entry), isolate); 12255 Handle<Object> element(dictionary->ValueAt(entry), isolate);
12269 PropertyDetails details = dictionary->DetailsAt(entry); 12256 PropertyDetails details = dictionary->DetailsAt(entry);
12270 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 12257 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
12271 return SetElementWithCallback(object, element, index, value, object, 12258 return SetElementWithCallback(object, element, index, value, object,
12272 strict_mode); 12259 strict_mode);
12273 } else { 12260 } else {
12274 dictionary->UpdateMaxNumberKey(index); 12261 dictionary->UpdateMaxNumberKey(index);
12275 // If a value has not been initialized we allow writing to it even if it 12262 // If a value has not been initialized we allow writing to it even if it
12276 // is read-only (a declared const that has not been initialized). If a 12263 // is read-only (a declared const that has not been initialized). If a
12277 // value is being defined we skip attribute checks completely. 12264 // value is being defined we skip attribute checks completely.
12278 if (set_mode == DEFINE_PROPERTY) { 12265 if (set_mode == DEFINE_PROPERTY) {
12279 details = PropertyDetails( 12266 details = PropertyDetails(
12280 attributes, NORMAL, details.dictionary_index()); 12267 attributes, NORMAL, details.dictionary_index());
12281 dictionary->DetailsAtPut(entry, details); 12268 dictionary->DetailsAtPut(entry, details);
12282 } else if (details.IsReadOnly() && !element->IsTheHole()) { 12269 } else if (details.IsReadOnly() && !element->IsTheHole()) {
12283 if (strict_mode == kNonStrictMode) { 12270 if (strict_mode == SLOPPY) {
12284 return isolate->factory()->undefined_value(); 12271 return isolate->factory()->undefined_value();
12285 } else { 12272 } else {
12286 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12273 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12287 Handle<Object> args[2] = { number, object }; 12274 Handle<Object> args[2] = { number, object };
12288 Handle<Object> error = 12275 Handle<Object> error =
12289 isolate->factory()->NewTypeError("strict_read_only_property", 12276 isolate->factory()->NewTypeError("strict_read_only_property",
12290 HandleVector(args, 2)); 12277 HandleVector(args, 2));
12291 isolate->Throw(*error); 12278 isolate->Throw(*error);
12292 return Handle<Object>(); 12279 return Handle<Object>();
12293 } 12280 }
(...skipping 17 matching lines...) Expand all
12311 if (check_prototype) { 12298 if (check_prototype) {
12312 bool found; 12299 bool found;
12313 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, 12300 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object,
12314 index, value, &found, strict_mode); 12301 index, value, &found, strict_mode);
12315 if (found) return result; 12302 if (found) return result;
12316 } 12303 }
12317 12304
12318 // When we set the is_extensible flag to false we always force the 12305 // When we set the is_extensible flag to false we always force the
12319 // element into dictionary mode (and force them to stay there). 12306 // element into dictionary mode (and force them to stay there).
12320 if (!object->map()->is_extensible()) { 12307 if (!object->map()->is_extensible()) {
12321 if (strict_mode == kNonStrictMode) { 12308 if (strict_mode == SLOPPY) {
12322 return isolate->factory()->undefined_value(); 12309 return isolate->factory()->undefined_value();
12323 } else { 12310 } else {
12324 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12311 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12325 Handle<String> name = isolate->factory()->NumberToString(number); 12312 Handle<String> name = isolate->factory()->NumberToString(number);
12326 Handle<Object> args[1] = { name }; 12313 Handle<Object> args[1] = { name };
12327 Handle<Object> error = 12314 Handle<Object> error =
12328 isolate->factory()->NewTypeError("object_not_extensible", 12315 isolate->factory()->NewTypeError("object_not_extensible",
12329 HandleVector(args, 1)); 12316 HandleVector(args, 1));
12330 isolate->Throw(*error); 12317 isolate->Throw(*error);
12331 return Handle<Object>(); 12318 return Handle<Object>();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
12384 } 12371 }
12385 #endif 12372 #endif
12386 } 12373 }
12387 return value; 12374 return value;
12388 } 12375 }
12389 12376
12390 Handle<Object> JSObject::SetFastDoubleElement( 12377 Handle<Object> JSObject::SetFastDoubleElement(
12391 Handle<JSObject> object, 12378 Handle<JSObject> object,
12392 uint32_t index, 12379 uint32_t index,
12393 Handle<Object> value, 12380 Handle<Object> value,
12394 StrictModeFlag strict_mode, 12381 StrictMode strict_mode,
12395 bool check_prototype) { 12382 bool check_prototype) {
12396 ASSERT(object->HasFastDoubleElements()); 12383 ASSERT(object->HasFastDoubleElements());
12397 12384
12398 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); 12385 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements()));
12399 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); 12386 uint32_t elms_length = static_cast<uint32_t>(base_elms->length());
12400 12387
12401 // If storing to an element that isn't in the array, pass the store request 12388 // If storing to an element that isn't in the array, pass the store request
12402 // up the prototype chain before storing in the receiver's elements. 12389 // up the prototype chain before storing in the receiver's elements.
12403 if (check_prototype && 12390 if (check_prototype &&
12404 (index >= elms_length || 12391 (index >= elms_length ||
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
12482 NormalizeElements(object); 12469 NormalizeElements(object);
12483 ASSERT(object->HasDictionaryElements()); 12470 ASSERT(object->HasDictionaryElements());
12484 return SetElement(object, index, value, NONE, strict_mode, check_prototype); 12471 return SetElement(object, index, value, NONE, strict_mode, check_prototype);
12485 } 12472 }
12486 12473
12487 12474
12488 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, 12475 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
12489 uint32_t index, 12476 uint32_t index,
12490 Handle<Object> value, 12477 Handle<Object> value,
12491 PropertyAttributes attributes, 12478 PropertyAttributes attributes,
12492 StrictModeFlag strict_mode) { 12479 StrictMode strict_mode) {
12493 if (object->IsJSProxy()) { 12480 if (object->IsJSProxy()) {
12494 return JSProxy::SetElementWithHandler( 12481 return JSProxy::SetElementWithHandler(
12495 Handle<JSProxy>::cast(object), object, index, value, strict_mode); 12482 Handle<JSProxy>::cast(object), object, index, value, strict_mode);
12496 } 12483 }
12497 return JSObject::SetElement( 12484 return JSObject::SetElement(
12498 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); 12485 Handle<JSObject>::cast(object), index, value, attributes, strict_mode);
12499 } 12486 }
12500 12487
12501 12488
12502 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, 12489 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
12503 uint32_t index, 12490 uint32_t index,
12504 Handle<Object> value, 12491 Handle<Object> value,
12505 StrictModeFlag strict_mode) { 12492 StrictMode strict_mode) {
12506 ASSERT(!object->HasExternalArrayElements()); 12493 ASSERT(!object->HasExternalArrayElements());
12507 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); 12494 return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
12508 } 12495 }
12509 12496
12510 12497
12511 Handle<Object> JSObject::SetElement(Handle<JSObject> object, 12498 Handle<Object> JSObject::SetElement(Handle<JSObject> object,
12512 uint32_t index, 12499 uint32_t index,
12513 Handle<Object> value, 12500 Handle<Object> value,
12514 PropertyAttributes attributes, 12501 PropertyAttributes attributes,
12515 StrictModeFlag strict_mode, 12502 StrictMode strict_mode,
12516 bool check_prototype, 12503 bool check_prototype,
12517 SetPropertyMode set_mode) { 12504 SetPropertyMode set_mode) {
12518 Isolate* isolate = object->GetIsolate(); 12505 Isolate* isolate = object->GetIsolate();
12519 12506
12520 if (object->HasExternalArrayElements()) { 12507 if (object->HasExternalArrayElements()) {
12521 if (!value->IsNumber() && !value->IsUndefined()) { 12508 if (!value->IsNumber() && !value->IsUndefined()) {
12522 bool has_exception; 12509 bool has_exception;
12523 Handle<Object> number = 12510 Handle<Object> number =
12524 Execution::ToNumber(isolate, value, &has_exception); 12511 Execution::ToNumber(isolate, value, &has_exception);
12525 if (has_exception) return Handle<Object>(); 12512 if (has_exception) return Handle<Object>();
12526 value = number; 12513 value = number;
12527 } 12514 }
12528 } 12515 }
12529 12516
12530 // Check access rights if needed. 12517 // Check access rights if needed.
12531 if (object->IsAccessCheckNeeded()) { 12518 if (object->IsAccessCheckNeeded()) {
12532 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) { 12519 if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) {
12533 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); 12520 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
12534 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 12521 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
12535 return value; 12522 return value;
12536 } 12523 }
12537 } 12524 }
12538 12525
12539 if (object->IsJSGlobalProxy()) { 12526 if (object->IsJSGlobalProxy()) {
12540 Handle<Object> proto(object->GetPrototype(), isolate); 12527 Handle<Object> proto(object->GetPrototype(), isolate);
12541 if (proto->IsNull()) return value; 12528 if (proto->IsNull()) return value;
12542 ASSERT(proto->IsJSGlobalObject()); 12529 ASSERT(proto->IsJSGlobalObject());
12543 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, 12530 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes,
(...skipping 12 matching lines...) Expand all
12556 return Handle<Object>(); 12543 return Handle<Object>();
12557 } 12544 }
12558 12545
12559 // Normalize the elements to enable attributes on the property. 12546 // Normalize the elements to enable attributes on the property.
12560 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { 12547 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
12561 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 12548 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
12562 // Make sure that we never go back to fast case. 12549 // Make sure that we never go back to fast case.
12563 dictionary->set_requires_slow_elements(); 12550 dictionary->set_requires_slow_elements();
12564 } 12551 }
12565 12552
12566 if (!(FLAG_harmony_observation && object->map()->is_observed())) { 12553 if (!object->map()->is_observed()) {
12567 return object->HasIndexedInterceptor() 12554 return object->HasIndexedInterceptor()
12568 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, 12555 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12569 check_prototype, 12556 check_prototype,
12570 set_mode) 12557 set_mode)
12571 : SetElementWithoutInterceptor(object, index, value, attributes, 12558 : SetElementWithoutInterceptor(object, index, value, attributes,
12572 strict_mode, 12559 strict_mode,
12573 check_prototype, 12560 check_prototype,
12574 set_mode); 12561 set_mode);
12575 } 12562 }
12576 12563
12577 PropertyAttributes old_attributes = object->GetLocalElementAttribute(index); 12564 PropertyAttributes old_attributes =
12565 JSReceiver::GetLocalElementAttribute(object, index);
12578 Handle<Object> old_value = isolate->factory()->the_hole_value(); 12566 Handle<Object> old_value = isolate->factory()->the_hole_value();
12579 Handle<Object> old_length_handle; 12567 Handle<Object> old_length_handle;
12580 Handle<Object> new_length_handle; 12568 Handle<Object> new_length_handle;
12581 12569
12582 if (old_attributes != ABSENT) { 12570 if (old_attributes != ABSENT) {
12583 if (object->GetLocalElementAccessorPair(index) == NULL) 12571 if (object->GetLocalElementAccessorPair(index) == NULL)
12584 old_value = Object::GetElement(isolate, object, index); 12572 old_value = Object::GetElement(isolate, object, index);
12585 } else if (object->IsJSArray()) { 12573 } else if (object->IsJSArray()) {
12586 // Store old array length in case adding an element grows the array. 12574 // Store old array length in case adding an element grows the array.
12587 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), 12575 old_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12588 isolate); 12576 isolate);
12589 } 12577 }
12590 12578
12591 // Check for lookup interceptor 12579 // Check for lookup interceptor
12592 Handle<Object> result = object->HasIndexedInterceptor() 12580 Handle<Object> result = object->HasIndexedInterceptor()
12593 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, 12581 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12594 check_prototype, 12582 check_prototype,
12595 set_mode) 12583 set_mode)
12596 : SetElementWithoutInterceptor(object, index, value, attributes, 12584 : SetElementWithoutInterceptor(object, index, value, attributes,
12597 strict_mode, 12585 strict_mode,
12598 check_prototype, 12586 check_prototype,
12599 set_mode); 12587 set_mode);
12600 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); 12588 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
12601 12589
12602 Handle<String> name = isolate->factory()->Uint32ToString(index); 12590 Handle<String> name = isolate->factory()->Uint32ToString(index);
12603 PropertyAttributes new_attributes = object->GetLocalElementAttribute(index); 12591 PropertyAttributes new_attributes = GetLocalElementAttribute(object, index);
12604 if (old_attributes == ABSENT) { 12592 if (old_attributes == ABSENT) {
12605 if (object->IsJSArray() && 12593 if (object->IsJSArray() &&
12606 !old_length_handle->SameValue( 12594 !old_length_handle->SameValue(
12607 Handle<JSArray>::cast(object)->length())) { 12595 Handle<JSArray>::cast(object)->length())) {
12608 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), 12596 new_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12609 isolate); 12597 isolate);
12610 uint32_t old_length = 0; 12598 uint32_t old_length = 0;
12611 uint32_t new_length = 0; 12599 uint32_t new_length = 0;
12612 CHECK(old_length_handle->ToArrayIndex(&old_length)); 12600 CHECK(old_length_handle->ToArrayIndex(&old_length));
12613 CHECK(new_length_handle->ToArrayIndex(&new_length)); 12601 CHECK(new_length_handle->ToArrayIndex(&new_length));
(...skipping 24 matching lines...) Expand all
12638 12626
12639 return result; 12627 return result;
12640 } 12628 }
12641 12629
12642 12630
12643 Handle<Object> JSObject::SetElementWithoutInterceptor( 12631 Handle<Object> JSObject::SetElementWithoutInterceptor(
12644 Handle<JSObject> object, 12632 Handle<JSObject> object,
12645 uint32_t index, 12633 uint32_t index,
12646 Handle<Object> value, 12634 Handle<Object> value,
12647 PropertyAttributes attributes, 12635 PropertyAttributes attributes,
12648 StrictModeFlag strict_mode, 12636 StrictMode strict_mode,
12649 bool check_prototype, 12637 bool check_prototype,
12650 SetPropertyMode set_mode) { 12638 SetPropertyMode set_mode) {
12651 ASSERT(object->HasDictionaryElements() || 12639 ASSERT(object->HasDictionaryElements() ||
12652 object->HasDictionaryArgumentsElements() || 12640 object->HasDictionaryArgumentsElements() ||
12653 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); 12641 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0);
12654 Isolate* isolate = object->GetIsolate(); 12642 Isolate* isolate = object->GetIsolate();
12655 if (FLAG_trace_external_array_abuse && 12643 if (FLAG_trace_external_array_abuse &&
12656 IsExternalArrayElementsKind(object->GetElementsKind())) { 12644 IsExternalArrayElementsKind(object->GetElementsKind())) {
12657 CheckArrayAbuse(*object, "external elements write", index); 12645 CheckArrayAbuse(*object, "external elements write", index);
12658 } 12646 }
(...skipping 27 matching lines...) Expand all
12686 } 12674 }
12687 12675
12688 TYPED_ARRAYS(TYPED_ARRAY_CASE) 12676 TYPED_ARRAYS(TYPED_ARRAY_CASE)
12689 12677
12690 #undef TYPED_ARRAY_CASE 12678 #undef TYPED_ARRAY_CASE
12691 12679
12692 case DICTIONARY_ELEMENTS: 12680 case DICTIONARY_ELEMENTS:
12693 return SetDictionaryElement(object, index, value, attributes, strict_mode, 12681 return SetDictionaryElement(object, index, value, attributes, strict_mode,
12694 check_prototype, 12682 check_prototype,
12695 set_mode); 12683 set_mode);
12696 case NON_STRICT_ARGUMENTS_ELEMENTS: { 12684 case SLOPPY_ARGUMENTS_ELEMENTS: {
12697 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 12685 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
12698 uint32_t length = parameter_map->length(); 12686 uint32_t length = parameter_map->length();
12699 Handle<Object> probe = index < length - 2 ? 12687 Handle<Object> probe = index < length - 2 ?
12700 Handle<Object>(parameter_map->get(index + 2), isolate) : 12688 Handle<Object>(parameter_map->get(index + 2), isolate) :
12701 Handle<Object>(); 12689 Handle<Object>();
12702 if (!probe.is_null() && !probe->IsTheHole()) { 12690 if (!probe.is_null() && !probe->IsTheHole()) {
12703 Handle<Context> context(Context::cast(parameter_map->get(0))); 12691 Handle<Context> context(Context::cast(parameter_map->get(0)));
12704 int context_index = Handle<Smi>::cast(probe)->value(); 12692 int context_index = Handle<Smi>::cast(probe)->value();
12705 ASSERT(!context->get(context_index)->IsTheHole()); 12693 ASSERT(!context->get(context_index)->IsTheHole());
12706 context->set(context_index, *value); 12694 context->set(context_index, *value);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
12899 (IsFastSmiOrObjectElementsKind(from_kind) && 12887 (IsFastSmiOrObjectElementsKind(from_kind) &&
12900 IsFastSmiOrObjectElementsKind(to_kind)) || 12888 IsFastSmiOrObjectElementsKind(to_kind)) ||
12901 (from_kind == FAST_DOUBLE_ELEMENTS && 12889 (from_kind == FAST_DOUBLE_ELEMENTS &&
12902 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { 12890 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12903 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); 12891 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12904 // No change is needed to the elements() buffer, the transition 12892 // No change is needed to the elements() buffer, the transition
12905 // only requires a map change. 12893 // only requires a map change.
12906 MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind); 12894 MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind);
12907 Map* new_map; 12895 Map* new_map;
12908 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 12896 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
12897 // TODO(verwaest): Replace by MigrateToMap.
12909 set_map(new_map); 12898 set_map(new_map);
12910 if (FLAG_trace_elements_transitions) { 12899 if (FLAG_trace_elements_transitions) {
12911 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 12900 FixedArrayBase* elms = FixedArrayBase::cast(elements());
12912 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms); 12901 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms);
12913 } 12902 }
12914 return this; 12903 return this;
12915 } 12904 }
12916 12905
12917 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 12906 FixedArrayBase* elms = FixedArrayBase::cast(elements());
12918 uint32_t capacity = static_cast<uint32_t>(elms->length()); 12907 uint32_t capacity = static_cast<uint32_t>(elms->length());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
13045 } 13034 }
13046 13035
13047 13036
13048 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { 13037 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
13049 *capacity = 0; 13038 *capacity = 0;
13050 *used = 0; 13039 *used = 0;
13051 13040
13052 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); 13041 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
13053 FixedArray* backing_store = NULL; 13042 FixedArray* backing_store = NULL;
13054 switch (GetElementsKind()) { 13043 switch (GetElementsKind()) {
13055 case NON_STRICT_ARGUMENTS_ELEMENTS: 13044 case SLOPPY_ARGUMENTS_ELEMENTS:
13056 backing_store_base = 13045 backing_store_base =
13057 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); 13046 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
13058 backing_store = FixedArray::cast(backing_store_base); 13047 backing_store = FixedArray::cast(backing_store_base);
13059 if (backing_store->IsDictionary()) { 13048 if (backing_store->IsDictionary()) {
13060 SeededNumberDictionary* dictionary = 13049 SeededNumberDictionary* dictionary =
13061 SeededNumberDictionary::cast(backing_store); 13050 SeededNumberDictionary::cast(backing_store);
13062 *capacity = dictionary->Capacity(); 13051 *capacity = dictionary->Capacity();
13063 *used = dictionary->NumberOfElements(); 13052 *used = dictionary->NumberOfElements();
13064 break; 13053 break;
13065 } 13054 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
13113 // External arrays are considered 100% used. 13102 // External arrays are considered 100% used.
13114 FixedArrayBase* external_array = FixedArrayBase::cast(elements()); 13103 FixedArrayBase* external_array = FixedArrayBase::cast(elements());
13115 *capacity = external_array->length(); 13104 *capacity = external_array->length();
13116 *used = external_array->length(); 13105 *used = external_array->length();
13117 break; 13106 break;
13118 } 13107 }
13119 } 13108 }
13120 } 13109 }
13121 13110
13122 13111
13112 bool JSObject::WouldConvertToSlowElements(Handle<Object> key) {
13113 uint32_t index;
13114 if (HasFastElements() && key->ToArrayIndex(&index)) {
13115 Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
13116 uint32_t capacity = static_cast<uint32_t>(backing_store->length());
13117 if (index >= capacity) {
13118 if ((index - capacity) >= kMaxGap) return true;
13119 uint32_t new_capacity = NewElementsCapacity(index + 1);
13120 return ShouldConvertToSlowElements(new_capacity);
13121 }
13122 }
13123 return false;
13124 }
13125
13126
13123 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { 13127 bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
13124 STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <= 13128 STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <=
13125 kMaxUncheckedFastElementsLength); 13129 kMaxUncheckedFastElementsLength);
13126 if (new_capacity <= kMaxUncheckedOldFastElementsLength || 13130 if (new_capacity <= kMaxUncheckedOldFastElementsLength ||
13127 (new_capacity <= kMaxUncheckedFastElementsLength && 13131 (new_capacity <= kMaxUncheckedFastElementsLength &&
13128 GetHeap()->InNewSpace(this))) { 13132 GetHeap()->InNewSpace(this))) {
13129 return false; 13133 return false;
13130 } 13134 }
13131 // If the fast-case backing storage takes up roughly three times as 13135 // If the fast-case backing storage takes up roughly three times as
13132 // much space (in machine words) as a dictionary backing storage 13136 // much space (in machine words) as a dictionary backing storage
13133 // would, the object should have slow elements. 13137 // would, the object should have slow elements.
13134 int old_capacity = 0; 13138 int old_capacity = 0;
13135 int used_elements = 0; 13139 int used_elements = 0;
13136 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 13140 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
13137 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) * 13141 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
13138 SeededNumberDictionary::kEntrySize; 13142 SeededNumberDictionary::kEntrySize;
13139 return 3 * dictionary_size <= new_capacity; 13143 return 3 * dictionary_size <= new_capacity;
13140 } 13144 }
13141 13145
13142 13146
13143 bool JSObject::ShouldConvertToFastElements() { 13147 bool JSObject::ShouldConvertToFastElements() {
13144 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 13148 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
13145 // If the elements are sparse, we should not go back to fast case. 13149 // If the elements are sparse, we should not go back to fast case.
13146 if (!HasDenseElements()) return false; 13150 if (!HasDenseElements()) return false;
13147 // An object requiring access checks is never allowed to have fast 13151 // An object requiring access checks is never allowed to have fast
13148 // elements. If it had fast elements we would skip security checks. 13152 // elements. If it had fast elements we would skip security checks.
13149 if (IsAccessCheckNeeded()) return false; 13153 if (IsAccessCheckNeeded()) return false;
13150 // Observed objects may not go to fast mode because they rely on map checks, 13154 // Observed objects may not go to fast mode because they rely on map checks,
13151 // and for fast element accesses we sometimes check element kinds only. 13155 // and for fast element accesses we sometimes check element kinds only.
13152 if (FLAG_harmony_observation && map()->is_observed()) return false; 13156 if (map()->is_observed()) return false;
13153 13157
13154 FixedArray* elements = FixedArray::cast(this->elements()); 13158 FixedArray* elements = FixedArray::cast(this->elements());
13155 SeededNumberDictionary* dictionary = NULL; 13159 SeededNumberDictionary* dictionary = NULL;
13156 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { 13160 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) {
13157 dictionary = SeededNumberDictionary::cast(elements->get(1)); 13161 dictionary = SeededNumberDictionary::cast(elements->get(1));
13158 } else { 13162 } else {
13159 dictionary = SeededNumberDictionary::cast(elements); 13163 dictionary = SeededNumberDictionary::cast(elements);
13160 } 13164 }
13161 // If an element has been added at a very high index in the elements 13165 // If an element has been added at a very high index in the elements
13162 // dictionary, we cannot go back to fast case. 13166 // dictionary, we cannot go back to fast case.
13163 if (dictionary->requires_slow_elements()) return false; 13167 if (dictionary->requires_slow_elements()) return false;
13164 // If the dictionary backing storage takes up roughly half as much 13168 // If the dictionary backing storage takes up roughly half as much
13165 // space (in machine words) as a fast-case backing storage would, 13169 // space (in machine words) as a fast-case backing storage would,
13166 // the object should have fast elements. 13170 // the object should have fast elements.
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
13336 return GetPropertyPostInterceptor(object, receiver, name, attributes); 13340 return GetPropertyPostInterceptor(object, receiver, name, attributes);
13337 } 13341 }
13338 13342
13339 13343
13340 bool JSObject::HasRealNamedProperty(Handle<JSObject> object, 13344 bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
13341 Handle<Name> key) { 13345 Handle<Name> key) {
13342 Isolate* isolate = object->GetIsolate(); 13346 Isolate* isolate = object->GetIsolate();
13343 SealHandleScope shs(isolate); 13347 SealHandleScope shs(isolate);
13344 // Check access rights if needed. 13348 // Check access rights if needed.
13345 if (object->IsAccessCheckNeeded()) { 13349 if (object->IsAccessCheckNeeded()) {
13346 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) { 13350 if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
13347 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 13351 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
13348 return false; 13352 return false;
13349 } 13353 }
13350 } 13354 }
13351 13355
13352 LookupResult result(isolate); 13356 LookupResult result(isolate);
13353 object->LocalLookupRealNamedProperty(*key, &result); 13357 object->LocalLookupRealNamedProperty(*key, &result);
13354 return result.IsFound() && !result.IsInterceptor(); 13358 return result.IsFound() && !result.IsInterceptor();
13355 } 13359 }
13356 13360
13357 13361
13358 bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) { 13362 bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
13359 Isolate* isolate = object->GetIsolate(); 13363 Isolate* isolate = object->GetIsolate();
13360 SealHandleScope shs(isolate); 13364 HandleScope scope(isolate);
13361 // Check access rights if needed. 13365 // Check access rights if needed.
13362 if (object->IsAccessCheckNeeded()) { 13366 if (object->IsAccessCheckNeeded()) {
13363 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS)) { 13367 if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
13364 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 13368 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
13365 return false; 13369 return false;
13366 } 13370 }
13367 } 13371 }
13368 13372
13369 if (object->IsJSGlobalProxy()) { 13373 if (object->IsJSGlobalProxy()) {
13370 HandleScope scope(isolate); 13374 HandleScope scope(isolate);
13371 Handle<Object> proto(object->GetPrototype(), isolate); 13375 Handle<Object> proto(object->GetPrototype(), isolate);
13372 if (proto->IsNull()) return false; 13376 if (proto->IsNull()) return false;
13373 ASSERT(proto->IsJSGlobalObject()); 13377 ASSERT(proto->IsJSGlobalObject());
13374 return HasRealElementProperty(Handle<JSObject>::cast(proto), index); 13378 return HasRealElementProperty(Handle<JSObject>::cast(proto), index);
13375 } 13379 }
13376 13380
13377 return object->GetElementAttributeWithoutInterceptor( 13381 return GetElementAttributeWithoutInterceptor(
13378 *object, index, false) != ABSENT; 13382 object, object, index, false) != ABSENT;
13379 } 13383 }
13380 13384
13381 13385
13382 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, 13386 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
13383 Handle<Name> key) { 13387 Handle<Name> key) {
13384 Isolate* isolate = object->GetIsolate(); 13388 Isolate* isolate = object->GetIsolate();
13385 SealHandleScope shs(isolate); 13389 SealHandleScope shs(isolate);
13386 // Check access rights if needed. 13390 // Check access rights if needed.
13387 if (object->IsAccessCheckNeeded()) { 13391 if (object->IsAccessCheckNeeded()) {
13388 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) { 13392 if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
13389 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 13393 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
13390 return false; 13394 return false;
13391 } 13395 }
13392 } 13396 }
13393 13397
13394 LookupResult result(isolate); 13398 LookupResult result(isolate);
13395 object->LocalLookupRealNamedProperty(*key, &result); 13399 object->LocalLookupRealNamedProperty(*key, &result);
13396 return result.IsPropertyCallbacks(); 13400 return result.IsPropertyCallbacks();
13397 } 13401 }
13398 13402
13399 13403
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
13626 13630
13627 case DICTIONARY_ELEMENTS: { 13631 case DICTIONARY_ELEMENTS: {
13628 if (storage != NULL) { 13632 if (storage != NULL) {
13629 element_dictionary()->CopyKeysTo(storage, 13633 element_dictionary()->CopyKeysTo(storage,
13630 filter, 13634 filter,
13631 SeededNumberDictionary::SORTED); 13635 SeededNumberDictionary::SORTED);
13632 } 13636 }
13633 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); 13637 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
13634 break; 13638 break;
13635 } 13639 }
13636 case NON_STRICT_ARGUMENTS_ELEMENTS: { 13640 case SLOPPY_ARGUMENTS_ELEMENTS: {
13637 FixedArray* parameter_map = FixedArray::cast(elements()); 13641 FixedArray* parameter_map = FixedArray::cast(elements());
13638 int mapped_length = parameter_map->length() - 2; 13642 int mapped_length = parameter_map->length() - 2;
13639 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 13643 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
13640 if (arguments->IsDictionary()) { 13644 if (arguments->IsDictionary()) {
13641 // Copy the keys from arguments first, because Dictionary::CopyKeysTo 13645 // Copy the keys from arguments first, because Dictionary::CopyKeysTo
13642 // will insert in storage starting at index 0. 13646 // will insert in storage starting at index 0.
13643 SeededNumberDictionary* dictionary = 13647 SeededNumberDictionary* dictionary =
13644 SeededNumberDictionary::cast(arguments); 13648 SeededNumberDictionary::cast(arguments);
13645 if (storage != NULL) { 13649 if (storage != NULL) {
13646 dictionary->CopyKeysTo( 13650 dictionary->CopyKeysTo(
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
13724 String* string_; 13728 String* string_;
13725 uint32_t hash_; 13729 uint32_t hash_;
13726 }; 13730 };
13727 13731
13728 13732
13729 // StringSharedKeys are used as keys in the eval cache. 13733 // StringSharedKeys are used as keys in the eval cache.
13730 class StringSharedKey : public HashTableKey { 13734 class StringSharedKey : public HashTableKey {
13731 public: 13735 public:
13732 StringSharedKey(String* source, 13736 StringSharedKey(String* source,
13733 SharedFunctionInfo* shared, 13737 SharedFunctionInfo* shared,
13734 LanguageMode language_mode, 13738 StrictMode strict_mode,
13735 int scope_position) 13739 int scope_position)
13736 : source_(source), 13740 : source_(source),
13737 shared_(shared), 13741 shared_(shared),
13738 language_mode_(language_mode), 13742 strict_mode_(strict_mode),
13739 scope_position_(scope_position) { } 13743 scope_position_(scope_position) { }
13740 13744
13741 bool IsMatch(Object* other) { 13745 bool IsMatch(Object* other) {
13742 if (!other->IsFixedArray()) return false; 13746 if (!other->IsFixedArray()) return false;
13743 FixedArray* other_array = FixedArray::cast(other); 13747 FixedArray* other_array = FixedArray::cast(other);
13744 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); 13748 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
13745 if (shared != shared_) return false; 13749 if (shared != shared_) return false;
13746 int language_unchecked = Smi::cast(other_array->get(2))->value(); 13750 int strict_unchecked = Smi::cast(other_array->get(2))->value();
13747 ASSERT(language_unchecked == CLASSIC_MODE || 13751 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
13748 language_unchecked == STRICT_MODE || 13752 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
13749 language_unchecked == EXTENDED_MODE); 13753 if (strict_mode != strict_mode_) return false;
13750 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
13751 if (language_mode != language_mode_) return false;
13752 int scope_position = Smi::cast(other_array->get(3))->value(); 13754 int scope_position = Smi::cast(other_array->get(3))->value();
13753 if (scope_position != scope_position_) return false; 13755 if (scope_position != scope_position_) return false;
13754 String* source = String::cast(other_array->get(1)); 13756 String* source = String::cast(other_array->get(1));
13755 return source->Equals(source_); 13757 return source->Equals(source_);
13756 } 13758 }
13757 13759
13758 static uint32_t StringSharedHashHelper(String* source, 13760 static uint32_t StringSharedHashHelper(String* source,
13759 SharedFunctionInfo* shared, 13761 SharedFunctionInfo* shared,
13760 LanguageMode language_mode, 13762 StrictMode strict_mode,
13761 int scope_position) { 13763 int scope_position) {
13762 uint32_t hash = source->Hash(); 13764 uint32_t hash = source->Hash();
13763 if (shared->HasSourceCode()) { 13765 if (shared->HasSourceCode()) {
13764 // Instead of using the SharedFunctionInfo pointer in the hash 13766 // Instead of using the SharedFunctionInfo pointer in the hash
13765 // code computation, we use a combination of the hash of the 13767 // code computation, we use a combination of the hash of the
13766 // script source code and the start position of the calling scope. 13768 // script source code and the start position of the calling scope.
13767 // We do this to ensure that the cache entries can survive garbage 13769 // We do this to ensure that the cache entries can survive garbage
13768 // collection. 13770 // collection.
13769 Script* script = Script::cast(shared->script()); 13771 Script* script = Script::cast(shared->script());
13770 hash ^= String::cast(script->source())->Hash(); 13772 hash ^= String::cast(script->source())->Hash();
13771 if (language_mode == STRICT_MODE) hash ^= 0x8000; 13773 if (strict_mode == STRICT) hash ^= 0x8000;
13772 if (language_mode == EXTENDED_MODE) hash ^= 0x0080;
13773 hash += scope_position; 13774 hash += scope_position;
13774 } 13775 }
13775 return hash; 13776 return hash;
13776 } 13777 }
13777 13778
13778 uint32_t Hash() { 13779 uint32_t Hash() {
13779 return StringSharedHashHelper( 13780 return StringSharedHashHelper(
13780 source_, shared_, language_mode_, scope_position_); 13781 source_, shared_, strict_mode_, scope_position_);
13781 } 13782 }
13782 13783
13783 uint32_t HashForObject(Object* obj) { 13784 uint32_t HashForObject(Object* obj) {
13784 FixedArray* other_array = FixedArray::cast(obj); 13785 FixedArray* other_array = FixedArray::cast(obj);
13785 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); 13786 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
13786 String* source = String::cast(other_array->get(1)); 13787 String* source = String::cast(other_array->get(1));
13787 int language_unchecked = Smi::cast(other_array->get(2))->value(); 13788 int strict_unchecked = Smi::cast(other_array->get(2))->value();
13788 ASSERT(language_unchecked == CLASSIC_MODE || 13789 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
13789 language_unchecked == STRICT_MODE || 13790 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
13790 language_unchecked == EXTENDED_MODE);
13791 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
13792 int scope_position = Smi::cast(other_array->get(3))->value(); 13791 int scope_position = Smi::cast(other_array->get(3))->value();
13793 return StringSharedHashHelper( 13792 return StringSharedHashHelper(
13794 source, shared, language_mode, scope_position); 13793 source, shared, strict_mode, scope_position);
13795 } 13794 }
13796 13795
13797 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { 13796 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
13798 Object* obj; 13797 Object* obj;
13799 { MaybeObject* maybe_obj = heap->AllocateFixedArray(4); 13798 { MaybeObject* maybe_obj = heap->AllocateFixedArray(4);
13800 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 13799 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
13801 } 13800 }
13802 FixedArray* other_array = FixedArray::cast(obj); 13801 FixedArray* other_array = FixedArray::cast(obj);
13803 other_array->set(0, shared_); 13802 other_array->set(0, shared_);
13804 other_array->set(1, source_); 13803 other_array->set(1, source_);
13805 other_array->set(2, Smi::FromInt(language_mode_)); 13804 other_array->set(2, Smi::FromInt(strict_mode_));
13806 other_array->set(3, Smi::FromInt(scope_position_)); 13805 other_array->set(3, Smi::FromInt(scope_position_));
13807 return other_array; 13806 return other_array;
13808 } 13807 }
13809 13808
13810 private: 13809 private:
13811 String* source_; 13810 String* source_;
13812 SharedFunctionInfo* shared_; 13811 SharedFunctionInfo* shared_;
13813 LanguageMode language_mode_; 13812 StrictMode strict_mode_;
13814 int scope_position_; 13813 int scope_position_;
13815 }; 13814 };
13816 13815
13817 13816
13818 // RegExpKey carries the source and flags of a regular expression as key. 13817 // RegExpKey carries the source and flags of a regular expression as key.
13819 class RegExpKey : public HashTableKey { 13818 class RegExpKey : public HashTableKey {
13820 public: 13819 public:
13821 RegExpKey(String* string, JSRegExp::Flags flags) 13820 RegExpKey(String* string, JSRegExp::Flags flags)
13822 : string_(string), 13821 : string_(string),
13823 flags_(Smi::FromInt(flags.value())) { } 13822 flags_(Smi::FromInt(flags.value())) { }
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
14439 } 14438 }
14440 14439
14441 14440
14442 // Collects all defined (non-hole) and non-undefined (array) elements at 14441 // Collects all defined (non-hole) and non-undefined (array) elements at
14443 // the start of the elements array. 14442 // the start of the elements array.
14444 // If the object is in dictionary mode, it is converted to fast elements 14443 // If the object is in dictionary mode, it is converted to fast elements
14445 // mode. 14444 // mode.
14446 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object, 14445 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14447 uint32_t limit) { 14446 uint32_t limit) {
14448 Isolate* isolate = object->GetIsolate(); 14447 Isolate* isolate = object->GetIsolate();
14448 if (object->HasSloppyArgumentsElements() ||
14449 object->map()->is_observed()) {
14450 return handle(Smi::FromInt(-1), isolate);
14451 }
14449 14452
14450 ASSERT(!object->map()->is_observed());
14451 if (object->HasDictionaryElements()) { 14453 if (object->HasDictionaryElements()) {
14452 // Convert to fast elements containing only the existing properties. 14454 // Convert to fast elements containing only the existing properties.
14453 // Ordering is irrelevant, since we are going to sort anyway. 14455 // Ordering is irrelevant, since we are going to sort anyway.
14454 Handle<SeededNumberDictionary> dict(object->element_dictionary()); 14456 Handle<SeededNumberDictionary> dict(object->element_dictionary());
14455 if (object->IsJSArray() || dict->requires_slow_elements() || 14457 if (object->IsJSArray() || dict->requires_slow_elements() ||
14456 dict->max_number_key() >= limit) { 14458 dict->max_number_key() >= limit) {
14457 return JSObject::PrepareSlowElementsForSort(object, limit); 14459 return JSObject::PrepareSlowElementsForSort(object, limit);
14458 } 14460 }
14459 // Convert to fast elements. 14461 // Convert to fast elements.
14460 14462
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
14996 14998
14997 // Add the new string and return it along with the string table. 14999 // Add the new string and return it along with the string table.
14998 entry = table->FindInsertionEntry(key->Hash()); 15000 entry = table->FindInsertionEntry(key->Hash());
14999 table->set(EntryToIndex(entry), string); 15001 table->set(EntryToIndex(entry), string);
15000 table->ElementAdded(); 15002 table->ElementAdded();
15001 *s = string; 15003 *s = string;
15002 return table; 15004 return table;
15003 } 15005 }
15004 15006
15005 15007
15006 // The key for the script compilation cache is dependent on the mode flags,
15007 // because they change the global language mode and thus binding behaviour.
15008 // If flags change at some point, we must ensure that we do not hit the cache
15009 // for code compiled with different settings.
15010 static LanguageMode CurrentGlobalLanguageMode() {
15011 return FLAG_use_strict
15012 ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE)
15013 : CLASSIC_MODE;
15014 }
15015
15016
15017 Object* CompilationCacheTable::Lookup(String* src, Context* context) { 15008 Object* CompilationCacheTable::Lookup(String* src, Context* context) {
15018 SharedFunctionInfo* shared = context->closure()->shared(); 15009 SharedFunctionInfo* shared = context->closure()->shared();
15019 StringSharedKey key(src, 15010 StringSharedKey key(src,
15020 shared, 15011 shared,
15021 CurrentGlobalLanguageMode(), 15012 FLAG_use_strict ? STRICT : SLOPPY,
15022 RelocInfo::kNoPosition); 15013 RelocInfo::kNoPosition);
15023 int entry = FindEntry(&key); 15014 int entry = FindEntry(&key);
15024 if (entry == kNotFound) return GetHeap()->undefined_value(); 15015 if (entry == kNotFound) return GetHeap()->undefined_value();
15025 return get(EntryToIndex(entry) + 1); 15016 return get(EntryToIndex(entry) + 1);
15026 } 15017 }
15027 15018
15028 15019
15029 Object* CompilationCacheTable::LookupEval(String* src, 15020 Object* CompilationCacheTable::LookupEval(String* src,
15030 Context* context, 15021 Context* context,
15031 LanguageMode language_mode, 15022 StrictMode strict_mode,
15032 int scope_position) { 15023 int scope_position) {
15033 StringSharedKey key(src, 15024 StringSharedKey key(src,
15034 context->closure()->shared(), 15025 context->closure()->shared(),
15035 language_mode, 15026 strict_mode,
15036 scope_position); 15027 scope_position);
15037 int entry = FindEntry(&key); 15028 int entry = FindEntry(&key);
15038 if (entry == kNotFound) return GetHeap()->undefined_value(); 15029 if (entry == kNotFound) return GetHeap()->undefined_value();
15039 return get(EntryToIndex(entry) + 1); 15030 return get(EntryToIndex(entry) + 1);
15040 } 15031 }
15041 15032
15042 15033
15043 Object* CompilationCacheTable::LookupRegExp(String* src, 15034 Object* CompilationCacheTable::LookupRegExp(String* src,
15044 JSRegExp::Flags flags) { 15035 JSRegExp::Flags flags) {
15045 RegExpKey key(src, flags); 15036 RegExpKey key(src, flags);
15046 int entry = FindEntry(&key); 15037 int entry = FindEntry(&key);
15047 if (entry == kNotFound) return GetHeap()->undefined_value(); 15038 if (entry == kNotFound) return GetHeap()->undefined_value();
15048 return get(EntryToIndex(entry) + 1); 15039 return get(EntryToIndex(entry) + 1);
15049 } 15040 }
15050 15041
15051 15042
15052 MaybeObject* CompilationCacheTable::Put(String* src, 15043 MaybeObject* CompilationCacheTable::Put(String* src,
15053 Context* context, 15044 Context* context,
15054 Object* value) { 15045 Object* value) {
15055 SharedFunctionInfo* shared = context->closure()->shared(); 15046 SharedFunctionInfo* shared = context->closure()->shared();
15056 StringSharedKey key(src, 15047 StringSharedKey key(src,
15057 shared, 15048 shared,
15058 CurrentGlobalLanguageMode(), 15049 FLAG_use_strict ? STRICT : SLOPPY,
15059 RelocInfo::kNoPosition); 15050 RelocInfo::kNoPosition);
15060 CompilationCacheTable* cache; 15051 CompilationCacheTable* cache;
15061 MaybeObject* maybe_cache = EnsureCapacity(1, &key); 15052 MaybeObject* maybe_cache = EnsureCapacity(1, &key);
15062 if (!maybe_cache->To(&cache)) return maybe_cache; 15053 if (!maybe_cache->To(&cache)) return maybe_cache;
15063 15054
15064 Object* k; 15055 Object* k;
15065 MaybeObject* maybe_k = key.AsObject(GetHeap()); 15056 MaybeObject* maybe_k = key.AsObject(GetHeap());
15066 if (!maybe_k->To(&k)) return maybe_k; 15057 if (!maybe_k->To(&k)) return maybe_k;
15067 15058
15068 int entry = cache->FindInsertionEntry(key.Hash()); 15059 int entry = cache->FindInsertionEntry(key.Hash());
15069 cache->set(EntryToIndex(entry), k); 15060 cache->set(EntryToIndex(entry), k);
15070 cache->set(EntryToIndex(entry) + 1, value); 15061 cache->set(EntryToIndex(entry) + 1, value);
15071 cache->ElementAdded(); 15062 cache->ElementAdded();
15072 return cache; 15063 return cache;
15073 } 15064 }
15074 15065
15075 15066
15076 MaybeObject* CompilationCacheTable::PutEval(String* src, 15067 MaybeObject* CompilationCacheTable::PutEval(String* src,
15077 Context* context, 15068 Context* context,
15078 SharedFunctionInfo* value, 15069 SharedFunctionInfo* value,
15079 int scope_position) { 15070 int scope_position) {
15080 StringSharedKey key(src, 15071 StringSharedKey key(src,
15081 context->closure()->shared(), 15072 context->closure()->shared(),
15082 value->language_mode(), 15073 value->strict_mode(),
15083 scope_position); 15074 scope_position);
15084 Object* obj; 15075 Object* obj;
15085 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 15076 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
15086 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15077 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
15087 } 15078 }
15088 15079
15089 CompilationCacheTable* cache = 15080 CompilationCacheTable* cache =
15090 reinterpret_cast<CompilationCacheTable*>(obj); 15081 reinterpret_cast<CompilationCacheTable*>(obj);
15091 int entry = cache->FindInsertionEntry(key.Hash()); 15082 int entry = cache->FindInsertionEntry(key.Hash());
15092 15083
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
15515 if ((attr & filter) == 0) result++; 15506 if ((attr & filter) == 0) result++;
15516 } 15507 }
15517 } 15508 }
15518 return result; 15509 return result;
15519 } 15510 }
15520 15511
15521 15512
15522 template<typename Shape, typename Key> 15513 template<typename Shape, typename Key>
15523 int Dictionary<Shape, Key>::NumberOfEnumElements() { 15514 int Dictionary<Shape, Key>::NumberOfEnumElements() {
15524 return NumberOfElementsFilterAttributes( 15515 return NumberOfElementsFilterAttributes(
15525 static_cast<PropertyAttributes>(DONT_ENUM)); 15516 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
15526 } 15517 }
15527 15518
15528 15519
15529 template<typename Shape, typename Key> 15520 template<typename Shape, typename Key>
15530 void Dictionary<Shape, Key>::CopyKeysTo( 15521 void Dictionary<Shape, Key>::CopyKeysTo(
15531 FixedArray* storage, 15522 FixedArray* storage,
15532 PropertyAttributes filter, 15523 PropertyAttributes filter,
15533 typename Dictionary<Shape, Key>::SortMode sort_mode) { 15524 typename Dictionary<Shape, Key>::SortMode sort_mode) {
15534 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); 15525 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter));
15535 int capacity = HashTable<Shape, Key>::Capacity(); 15526 int capacity = HashTable<Shape, Key>::Capacity();
15536 int index = 0; 15527 int index = 0;
15537 for (int i = 0; i < capacity; i++) { 15528 for (int i = 0; i < capacity; i++) {
15538 Object* k = HashTable<Shape, Key>::KeyAt(i); 15529 Object* k = HashTable<Shape, Key>::KeyAt(i);
15539 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { 15530 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) {
15540 PropertyDetails details = DetailsAt(i); 15531 PropertyDetails details = DetailsAt(i);
15541 if (details.IsDeleted()) continue; 15532 if (details.IsDeleted()) continue;
15542 PropertyAttributes attr = details.attributes(); 15533 PropertyAttributes attr = details.attributes();
15543 if ((attr & filter) == 0) storage->set(index++, k); 15534 if ((attr & filter) == 0) storage->set(index++, k);
15544 } 15535 }
15545 } 15536 }
15546 if (sort_mode == Dictionary<Shape, Key>::SORTED) { 15537 if (sort_mode == Dictionary<Shape, Key>::SORTED) {
15547 storage->SortPairs(storage, index); 15538 storage->SortPairs(storage, index);
15548 } 15539 }
15549 ASSERT(storage->length() >= index); 15540 ASSERT(storage->length() >= index);
15550 } 15541 }
15551 15542
15552 15543
15553 FixedArray* NameDictionary::CopyEnumKeysTo(FixedArray* storage) { 15544 struct EnumIndexComparator {
15545 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { }
15546 bool operator() (Smi* a, Smi* b) {
15547 PropertyDetails da(dict->DetailsAt(a->value()));
15548 PropertyDetails db(dict->DetailsAt(b->value()));
15549 return da.dictionary_index() < db.dictionary_index();
15550 }
15551 NameDictionary* dict;
15552 };
15553
15554
15555 void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
15554 int length = storage->length(); 15556 int length = storage->length();
15555 ASSERT(length >= NumberOfEnumElements());
15556 Heap* heap = GetHeap();
15557 Object* undefined_value = heap->undefined_value();
15558 int capacity = Capacity(); 15557 int capacity = Capacity();
15559 int properties = 0; 15558 int properties = 0;
15560
15561 // Fill in the enumeration array by assigning enumerable keys at their
15562 // enumeration index. This will leave holes in the array if there are keys
15563 // that are deleted or not enumerable.
15564 for (int i = 0; i < capacity; i++) { 15559 for (int i = 0; i < capacity; i++) {
15565 Object* k = KeyAt(i); 15560 Object* k = KeyAt(i);
15566 if (IsKey(k) && !k->IsSymbol()) { 15561 if (IsKey(k) && !k->IsSymbol()) {
15567 PropertyDetails details = DetailsAt(i); 15562 PropertyDetails details = DetailsAt(i);
15568 if (details.IsDeleted() || details.IsDontEnum()) continue; 15563 if (details.IsDeleted() || details.IsDontEnum()) continue;
15564 storage->set(properties, Smi::FromInt(i));
15569 properties++; 15565 properties++;
15570 storage->set(details.dictionary_index() - 1, k);
15571 if (properties == length) break; 15566 if (properties == length) break;
15572 } 15567 }
15573 } 15568 }
15574 15569 EnumIndexComparator cmp(this);
15575 // There are holes in the enumeration array if less properties were assigned 15570 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
15576 // than the length of the array. If so, crunch all the existing properties 15571 std::sort(start, start + length, cmp);
15577 // together by shifting them to the left (maintaining the enumeration order), 15572 for (int i = 0; i < length; i++) {
15578 // and trimming of the right side of the array. 15573 int index = Smi::cast(storage->get(i))->value();
15579 if (properties < length) { 15574 storage->set(i, KeyAt(index));
15580 if (properties == 0) return heap->empty_fixed_array();
15581 properties = 0;
15582 for (int i = 0; i < length; ++i) {
15583 Object* value = storage->get(i);
15584 if (value != undefined_value) {
15585 storage->set(properties, value);
15586 ++properties;
15587 }
15588 }
15589 RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties);
15590 } 15575 }
15591 return storage;
15592 } 15576 }
15593 15577
15594 15578
15595 template<typename Shape, typename Key> 15579 template<typename Shape, typename Key>
15596 void Dictionary<Shape, Key>::CopyKeysTo( 15580 void Dictionary<Shape, Key>::CopyKeysTo(
15597 FixedArray* storage, 15581 FixedArray* storage,
15598 int index, 15582 int index,
15599 PropertyAttributes filter, 15583 PropertyAttributes filter,
15600 typename Dictionary<Shape, Key>::SortMode sort_mode) { 15584 typename Dictionary<Shape, Key>::SortMode sort_mode) {
15601 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); 15585 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter));
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
15717 if (IsKey(k)) { 15701 if (IsKey(k)) {
15718 Object* value = ValueAt(i); 15702 Object* value = ValueAt(i);
15719 Name* key; 15703 Name* key;
15720 if (k->IsSymbol()) { 15704 if (k->IsSymbol()) {
15721 key = Symbol::cast(k); 15705 key = Symbol::cast(k);
15722 } else { 15706 } else {
15723 // Ensure the key is a unique name before writing into the 15707 // Ensure the key is a unique name before writing into the
15724 // instance descriptor. 15708 // instance descriptor.
15725 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); 15709 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
15726 if (!maybe_key->To(&key)) return maybe_key; 15710 if (!maybe_key->To(&key)) return maybe_key;
15727 if (key->Equals(heap->empty_string())) return this;
15728 } 15711 }
15729 15712
15730 PropertyDetails details = DetailsAt(i); 15713 PropertyDetails details = DetailsAt(i);
15731 int enumeration_index = details.dictionary_index(); 15714 int enumeration_index = details.dictionary_index();
15732 PropertyType type = details.type(); 15715 PropertyType type = details.type();
15733 15716
15734 if (value->IsJSFunction()) { 15717 if (value->IsJSFunction()) {
15735 ConstantDescriptor d(key, value, details.attributes()); 15718 ConstantDescriptor d(key, value, details.attributes());
15736 descriptors->Set(enumeration_index - 1, &d, witness); 15719 descriptors->Set(enumeration_index - 1, &d, witness);
15737 } else if (type == NORMAL) { 15720 } else if (type == NORMAL) {
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after
16497 #define ERROR_MESSAGES_TEXTS(C, T) T, 16480 #define ERROR_MESSAGES_TEXTS(C, T) T,
16498 static const char* error_messages_[] = { 16481 static const char* error_messages_[] = {
16499 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16482 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16500 }; 16483 };
16501 #undef ERROR_MESSAGES_TEXTS 16484 #undef ERROR_MESSAGES_TEXTS
16502 return error_messages_[reason]; 16485 return error_messages_[reason];
16503 } 16486 }
16504 16487
16505 16488
16506 } } // namespace v8::internal 16489 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698