OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 if (value->IsFixedArray()) { | 323 if (value->IsFixedArray()) { |
324 // The value contains the constant_properties of a | 324 // The value contains the constant_properties of a |
325 // simple object literal. | 325 // simple object literal. |
326 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 326 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
327 value = CreateLiteralBoilerplate(literals, array); | 327 value = CreateLiteralBoilerplate(literals, array); |
328 if (value.is_null()) return value; | 328 if (value.is_null()) return value; |
329 } | 329 } |
330 Handle<Object> result; | 330 Handle<Object> result; |
331 uint32_t element_index = 0; | 331 uint32_t element_index = 0; |
332 if (key->IsSymbol()) { | 332 if (key->IsSymbol()) { |
333 // If key is a symbol it is not an array element. | 333 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |
334 Handle<String> name(String::cast(*key)); | 334 // Array index as string (uint32). |
335 ASSERT(!name->AsArrayIndex(&element_index)); | 335 result = SetOwnElement(boilerplate, element_index, value); |
336 result = SetProperty(boilerplate, name, value, NONE); | 336 } else { |
| 337 Handle<String> name(String::cast(*key)); |
| 338 ASSERT(!name->AsArrayIndex(&element_index)); |
| 339 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, |
| 340 value, NONE); |
| 341 } |
337 } else if (key->ToArrayIndex(&element_index)) { | 342 } else if (key->ToArrayIndex(&element_index)) { |
338 // Array index (uint32). | 343 // Array index (uint32). |
339 result = SetElement(boilerplate, element_index, value); | 344 result = SetOwnElement(boilerplate, element_index, value); |
340 } else { | 345 } else { |
341 // Non-uint32 number. | 346 // Non-uint32 number. |
342 ASSERT(key->IsNumber()); | 347 ASSERT(key->IsNumber()); |
343 double num = key->Number(); | 348 double num = key->Number(); |
344 char arr[100]; | 349 char arr[100]; |
345 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 350 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
346 const char* str = DoubleToCString(num, buffer); | 351 const char* str = DoubleToCString(num, buffer); |
347 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); | 352 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); |
348 result = SetProperty(boilerplate, name, value, NONE); | 353 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, |
| 354 value, NONE); |
349 } | 355 } |
350 // If setting the property on the boilerplate throws an | 356 // If setting the property on the boilerplate throws an |
351 // exception, the exception is converted to an empty handle in | 357 // exception, the exception is converted to an empty handle in |
352 // the handle based operations. In that case, we need to | 358 // the handle based operations. In that case, we need to |
353 // convert back to an exception. | 359 // convert back to an exception. |
354 if (result.is_null()) return result; | 360 if (result.is_null()) return result; |
355 } | 361 } |
356 } | 362 } |
357 | 363 |
358 return boilerplate; | 364 return boilerplate; |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 return ThrowRedeclarationError(type, name); | 983 return ThrowRedeclarationError(type, name); |
978 } | 984 } |
979 SetProperty(global, name, value, attributes); | 985 SetProperty(global, name, value, attributes); |
980 } else { | 986 } else { |
981 // If a property with this name does not already exist on the | 987 // If a property with this name does not already exist on the |
982 // global object add the property locally. We take special | 988 // global object add the property locally. We take special |
983 // precautions to always add it as a local property even in case | 989 // precautions to always add it as a local property even in case |
984 // of callbacks in the prototype chain (this rules out using | 990 // of callbacks in the prototype chain (this rules out using |
985 // SetProperty). Also, we must use the handle-based version to | 991 // SetProperty). Also, we must use the handle-based version to |
986 // avoid GC issues. | 992 // avoid GC issues. |
987 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); | 993 SetLocalPropertyIgnoreAttributes(global, name, value, attributes); |
988 } | 994 } |
989 } | 995 } |
990 | 996 |
991 return Heap::undefined_value(); | 997 return Heap::undefined_value(); |
992 } | 998 } |
993 | 999 |
994 | 1000 |
995 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { | 1001 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { |
996 HandleScope scope; | 1002 HandleScope scope; |
997 ASSERT(args.length() == 4); | 1003 ASSERT(args.length() == 4); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 // not be deletable. | 1098 // not be deletable. |
1093 PropertyAttributes attributes = DONT_DELETE; | 1099 PropertyAttributes attributes = DONT_DELETE; |
1094 | 1100 |
1095 // Lookup the property locally in the global object. If it isn't | 1101 // Lookup the property locally in the global object. If it isn't |
1096 // there, there is a property with this name in the prototype chain. | 1102 // there, there is a property with this name in the prototype chain. |
1097 // We follow Safari and Firefox behavior and only set the property | 1103 // We follow Safari and Firefox behavior and only set the property |
1098 // locally if there is an explicit initialization value that we have | 1104 // locally if there is an explicit initialization value that we have |
1099 // to assign to the property. When adding the property we take | 1105 // to assign to the property. When adding the property we take |
1100 // special precautions to always add it as a local property even in | 1106 // special precautions to always add it as a local property even in |
1101 // case of callbacks in the prototype chain (this rules out using | 1107 // case of callbacks in the prototype chain (this rules out using |
1102 // SetProperty). We have IgnoreAttributesAndSetLocalProperty for | 1108 // SetProperty). We have SetLocalPropertyIgnoreAttributes for |
1103 // this. | 1109 // this. |
1104 // Note that objects can have hidden prototypes, so we need to traverse | 1110 // Note that objects can have hidden prototypes, so we need to traverse |
1105 // the whole chain of hidden prototypes to do a 'local' lookup. | 1111 // the whole chain of hidden prototypes to do a 'local' lookup. |
1106 JSObject* real_holder = global; | 1112 JSObject* real_holder = global; |
1107 LookupResult lookup; | 1113 LookupResult lookup; |
1108 while (true) { | 1114 while (true) { |
1109 real_holder->LocalLookup(*name, &lookup); | 1115 real_holder->LocalLookup(*name, &lookup); |
1110 if (lookup.IsProperty()) { | 1116 if (lookup.IsProperty()) { |
1111 // Determine if this is a redeclaration of something read-only. | 1117 // Determine if this is a redeclaration of something read-only. |
1112 if (lookup.IsReadOnly()) { | 1118 if (lookup.IsReadOnly()) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 break; | 1161 break; |
1156 | 1162 |
1157 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) | 1163 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) |
1158 break; | 1164 break; |
1159 | 1165 |
1160 real_holder = JSObject::cast(proto); | 1166 real_holder = JSObject::cast(proto); |
1161 } | 1167 } |
1162 | 1168 |
1163 global = Top::context()->global(); | 1169 global = Top::context()->global(); |
1164 if (assign) { | 1170 if (assign) { |
1165 return global->IgnoreAttributesAndSetLocalProperty(*name, | 1171 return global->SetLocalPropertyIgnoreAttributes(*name, |
1166 args[1], | 1172 args[1], |
1167 attributes); | 1173 attributes); |
1168 } | 1174 } |
1169 return Heap::undefined_value(); | 1175 return Heap::undefined_value(); |
1170 } | 1176 } |
1171 | 1177 |
1172 | 1178 |
1173 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { | 1179 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { |
1174 // All constants are declared with an initial value. The name | 1180 // All constants are declared with an initial value. The name |
1175 // of the constant is the first argument and the initial value | 1181 // of the constant is the first argument and the initial value |
1176 // is the second. | 1182 // is the second. |
1177 RUNTIME_ASSERT(args.length() == 2); | 1183 RUNTIME_ASSERT(args.length() == 2); |
1178 CONVERT_ARG_CHECKED(String, name, 0); | 1184 CONVERT_ARG_CHECKED(String, name, 0); |
1179 Handle<Object> value = args.at<Object>(1); | 1185 Handle<Object> value = args.at<Object>(1); |
1180 | 1186 |
1181 // Get the current global object from top. | 1187 // Get the current global object from top. |
1182 GlobalObject* global = Top::context()->global(); | 1188 GlobalObject* global = Top::context()->global(); |
1183 | 1189 |
1184 // According to ECMA-262, section 12.2, page 62, the property must | 1190 // According to ECMA-262, section 12.2, page 62, the property must |
1185 // not be deletable. Since it's a const, it must be READ_ONLY too. | 1191 // not be deletable. Since it's a const, it must be READ_ONLY too. |
1186 PropertyAttributes attributes = | 1192 PropertyAttributes attributes = |
1187 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 1193 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
1188 | 1194 |
1189 // Lookup the property locally in the global object. If it isn't | 1195 // Lookup the property locally in the global object. If it isn't |
1190 // there, we add the property and take special precautions to always | 1196 // there, we add the property and take special precautions to always |
1191 // add it as a local property even in case of callbacks in the | 1197 // add it as a local property even in case of callbacks in the |
1192 // prototype chain (this rules out using SetProperty). | 1198 // prototype chain (this rules out using SetProperty). |
1193 // We use IgnoreAttributesAndSetLocalProperty instead | 1199 // We use SetLocalPropertyIgnoreAttributes instead |
1194 LookupResult lookup; | 1200 LookupResult lookup; |
1195 global->LocalLookup(*name, &lookup); | 1201 global->LocalLookup(*name, &lookup); |
1196 if (!lookup.IsProperty()) { | 1202 if (!lookup.IsProperty()) { |
1197 return global->IgnoreAttributesAndSetLocalProperty(*name, | 1203 return global->SetLocalPropertyIgnoreAttributes(*name, |
1198 *value, | 1204 *value, |
1199 attributes); | 1205 attributes); |
1200 } | 1206 } |
1201 | 1207 |
1202 // Determine if this is a redeclaration of something not | 1208 // Determine if this is a redeclaration of something not |
1203 // read-only. In case the result is hidden behind an interceptor we | 1209 // read-only. In case the result is hidden behind an interceptor we |
1204 // need to ask it for the property attributes. | 1210 // need to ask it for the property attributes. |
1205 if (!lookup.IsReadOnly()) { | 1211 if (!lookup.IsReadOnly()) { |
1206 if (lookup.type() != INTERCEPTOR) { | 1212 if (lookup.type() != INTERCEPTOR) { |
1207 return ThrowRedeclarationError("var", name); | 1213 return ThrowRedeclarationError("var", name); |
1208 } | 1214 } |
1209 | 1215 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 } | 1466 } |
1461 | 1467 |
1462 // Map has changed, so use generic, but slower, method. Since these | 1468 // Map has changed, so use generic, but slower, method. Since these |
1463 // properties were all added as DONT_DELETE they must be present and | 1469 // properties were all added as DONT_DELETE they must be present and |
1464 // normal so no failures can be expected. | 1470 // normal so no failures can be expected. |
1465 PropertyAttributes final = | 1471 PropertyAttributes final = |
1466 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1472 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
1467 PropertyAttributes writable = | 1473 PropertyAttributes writable = |
1468 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1474 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
1469 MaybeObject* result; | 1475 MaybeObject* result; |
1470 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(), | 1476 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::source_symbol(), |
1471 source, | 1477 source, |
1472 final); | 1478 final); |
1473 ASSERT(!result->IsFailure()); | 1479 ASSERT(!result->IsFailure()); |
1474 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(), | 1480 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::global_symbol(), |
1475 global, | 1481 global, |
1476 final); | 1482 final); |
1477 ASSERT(!result->IsFailure()); | 1483 ASSERT(!result->IsFailure()); |
1478 result = | 1484 result = |
1479 regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(), | 1485 regexp->SetLocalPropertyIgnoreAttributes(Heap::ignore_case_symbol(), |
1480 ignoreCase, | 1486 ignoreCase, |
1481 final); | 1487 final); |
1482 ASSERT(!result->IsFailure()); | 1488 ASSERT(!result->IsFailure()); |
1483 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(), | 1489 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::multiline_symbol(), |
1484 multiline, | 1490 multiline, |
1485 final); | 1491 final); |
1486 ASSERT(!result->IsFailure()); | 1492 ASSERT(!result->IsFailure()); |
1487 result = | 1493 result = |
1488 regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(), | 1494 regexp->SetLocalPropertyIgnoreAttributes(Heap::last_index_symbol(), |
1489 Smi::FromInt(0), | 1495 Smi::FromInt(0), |
1490 writable); | 1496 writable); |
1491 ASSERT(!result->IsFailure()); | 1497 ASSERT(!result->IsFailure()); |
1492 USE(result); | 1498 USE(result); |
1493 return regexp; | 1499 return regexp; |
1494 } | 1500 } |
1495 | 1501 |
1496 | 1502 |
1497 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) { | 1503 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) { |
1498 HandleScope scope; | 1504 HandleScope scope; |
1499 ASSERT(args.length() == 1); | 1505 ASSERT(args.length() == 1); |
1500 CONVERT_ARG_CHECKED(JSArray, prototype, 0); | 1506 CONVERT_ARG_CHECKED(JSArray, prototype, 0); |
(...skipping 2063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3564 // to not worry about changing the instance_descriptor and creating a new | 3570 // to not worry about changing the instance_descriptor and creating a new |
3565 // map. The current version of SetObjectProperty does not handle attributes | 3571 // map. The current version of SetObjectProperty does not handle attributes |
3566 // correctly in the case where a property is a field and is reset with | 3572 // correctly in the case where a property is a field and is reset with |
3567 // new attributes. | 3573 // new attributes. |
3568 if (result.IsProperty() && | 3574 if (result.IsProperty() && |
3569 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 3575 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { |
3570 // New attributes - normalize to avoid writing to instance descriptor | 3576 // New attributes - normalize to avoid writing to instance descriptor |
3571 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 3577 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
3572 // Use IgnoreAttributes version since a readonly property may be | 3578 // Use IgnoreAttributes version since a readonly property may be |
3573 // overridden and SetProperty does not allow this. | 3579 // overridden and SetProperty does not allow this. |
3574 return js_object->IgnoreAttributesAndSetLocalProperty(*name, | 3580 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
3575 *obj_value, | 3581 *obj_value, |
3576 attr); | 3582 attr); |
3577 } | 3583 } |
3578 | 3584 |
3579 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); | 3585 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); |
3580 } | 3586 } |
3581 | 3587 |
3582 | 3588 |
3583 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, | 3589 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
3584 Handle<Object> key, | 3590 Handle<Object> key, |
3585 Handle<Object> value, | 3591 Handle<Object> value, |
3586 PropertyAttributes attr) { | 3592 PropertyAttributes attr) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3667 | 3673 |
3668 return js_object->SetElement(index, *value); | 3674 return js_object->SetElement(index, *value); |
3669 } | 3675 } |
3670 | 3676 |
3671 if (key->IsString()) { | 3677 if (key->IsString()) { |
3672 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 3678 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
3673 return js_object->SetElement(index, *value); | 3679 return js_object->SetElement(index, *value); |
3674 } else { | 3680 } else { |
3675 Handle<String> key_string = Handle<String>::cast(key); | 3681 Handle<String> key_string = Handle<String>::cast(key); |
3676 key_string->TryFlatten(); | 3682 key_string->TryFlatten(); |
3677 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string, | 3683 return js_object->SetLocalPropertyIgnoreAttributes(*key_string, |
3678 *value, | 3684 *value, |
3679 attr); | 3685 attr); |
3680 } | 3686 } |
3681 } | 3687 } |
3682 | 3688 |
3683 // Call-back into JavaScript to convert the key to a string. | 3689 // Call-back into JavaScript to convert the key to a string. |
3684 bool has_pending_exception = false; | 3690 bool has_pending_exception = false; |
3685 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 3691 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
3686 if (has_pending_exception) return Failure::Exception(); | 3692 if (has_pending_exception) return Failure::Exception(); |
3687 Handle<String> name = Handle<String>::cast(converted); | 3693 Handle<String> name = Handle<String>::cast(converted); |
3688 | 3694 |
3689 if (name->AsArrayIndex(&index)) { | 3695 if (name->AsArrayIndex(&index)) { |
3690 return js_object->SetElement(index, *value); | 3696 return js_object->SetElement(index, *value); |
3691 } else { | 3697 } else { |
3692 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr); | 3698 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); |
3693 } | 3699 } |
3694 } | 3700 } |
3695 | 3701 |
3696 | 3702 |
3697 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, | 3703 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, |
3698 Handle<Object> key) { | 3704 Handle<Object> key) { |
3699 HandleScope scope; | 3705 HandleScope scope; |
3700 | 3706 |
3701 // Check if the given key is an array index. | 3707 // Check if the given key is an array index. |
3702 uint32_t index; | 3708 uint32_t index; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3764 if (args.length() == 4) { | 3770 if (args.length() == 4) { |
3765 CONVERT_CHECKED(Smi, value_obj, args[3]); | 3771 CONVERT_CHECKED(Smi, value_obj, args[3]); |
3766 int unchecked_value = value_obj->value(); | 3772 int unchecked_value = value_obj->value(); |
3767 // Only attribute bits should be set. | 3773 // Only attribute bits should be set. |
3768 RUNTIME_ASSERT( | 3774 RUNTIME_ASSERT( |
3769 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3775 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3770 attributes = static_cast<PropertyAttributes>(unchecked_value); | 3776 attributes = static_cast<PropertyAttributes>(unchecked_value); |
3771 } | 3777 } |
3772 | 3778 |
3773 return object-> | 3779 return object-> |
3774 IgnoreAttributesAndSetLocalProperty(name, args[2], attributes); | 3780 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); |
3775 } | 3781 } |
3776 | 3782 |
3777 | 3783 |
3778 static MaybeObject* Runtime_DeleteProperty(Arguments args) { | 3784 static MaybeObject* Runtime_DeleteProperty(Arguments args) { |
3779 NoHandleAllocation ha; | 3785 NoHandleAllocation ha; |
3780 ASSERT(args.length() == 2); | 3786 ASSERT(args.length() == 2); |
3781 | 3787 |
3782 CONVERT_CHECKED(JSObject, object, args[0]); | 3788 CONVERT_CHECKED(JSObject, object, args[0]); |
3783 CONVERT_CHECKED(String, key, args[1]); | 3789 CONVERT_CHECKED(String, key, args[1]); |
3784 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); | 3790 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); |
(...skipping 7037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10822 } else { | 10828 } else { |
10823 // Handle last resort GC and make sure to allow future allocations | 10829 // Handle last resort GC and make sure to allow future allocations |
10824 // to grow the heap without causing GCs (if possible). | 10830 // to grow the heap without causing GCs (if possible). |
10825 Counters::gc_last_resort_from_js.Increment(); | 10831 Counters::gc_last_resort_from_js.Increment(); |
10826 Heap::CollectAllGarbage(false); | 10832 Heap::CollectAllGarbage(false); |
10827 } | 10833 } |
10828 } | 10834 } |
10829 | 10835 |
10830 | 10836 |
10831 } } // namespace v8::internal | 10837 } } // namespace v8::internal |
OLD | NEW |