OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 CONVERT_CHECKED(String, name, args[1]); | 589 CONVERT_CHECKED(String, name, args[1]); |
590 | 590 |
591 // Use recursive implementation to also traverse hidden prototypes | 591 // Use recursive implementation to also traverse hidden prototypes |
592 GetOwnPropertyImplementation(obj, name, &result); | 592 GetOwnPropertyImplementation(obj, name, &result); |
593 | 593 |
594 if (!result.IsProperty()) | 594 if (!result.IsProperty()) |
595 return Heap::undefined_value(); | 595 return Heap::undefined_value(); |
596 | 596 |
597 if (result.type() == CALLBACKS) { | 597 if (result.type() == CALLBACKS) { |
598 Object* structure = result.GetCallbackObject(); | 598 Object* structure = result.GetCallbackObject(); |
599 if (structure->IsProxy()) { | 599 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
600 // Property that is internally implemented as a callback. | 600 // Property that is internally implemented as a callback or |
| 601 // an API defined callback. |
601 Object* value = obj->GetPropertyWithCallback( | 602 Object* value = obj->GetPropertyWithCallback( |
602 obj, structure, name, result.holder()); | 603 obj, structure, name, result.holder()); |
603 elms->set(0, Heap::false_value()); | 604 elms->set(0, Heap::false_value()); |
604 elms->set(1, value); | 605 elms->set(1, value); |
605 elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); | 606 elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); |
606 } else if (structure->IsFixedArray()) { | 607 } else if (structure->IsFixedArray()) { |
607 // __defineGetter__/__defineSetter__ callback. | 608 // __defineGetter__/__defineSetter__ callback. |
608 elms->set(0, Heap::true_value()); | 609 elms->set(0, Heap::true_value()); |
609 elms->set(1, FixedArray::cast(structure)->get(0)); | 610 elms->set(1, FixedArray::cast(structure)->get(0)); |
610 elms->set(2, FixedArray::cast(structure)->get(1)); | 611 elms->set(2, FixedArray::cast(structure)->get(1)); |
611 } else { | 612 } else { |
612 // TODO(ricow): Handle API callbacks. | |
613 return Heap::undefined_value(); | 613 return Heap::undefined_value(); |
614 } | 614 } |
615 } else { | 615 } else { |
616 elms->set(0, Heap::false_value()); | 616 elms->set(0, Heap::false_value()); |
617 elms->set(1, result.GetLazyValue()); | 617 elms->set(1, result.GetLazyValue()); |
618 elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); | 618 elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); |
619 } | 619 } |
620 | 620 |
621 elms->set(3, Heap::ToBoolean(!result.IsDontEnum())); | 621 elms->set(3, Heap::ToBoolean(!result.IsDontEnum())); |
622 elms->set(4, Heap::ToBoolean(!result.IsReadOnly())); | 622 elms->set(4, Heap::ToBoolean(!result.IsDontDelete())); |
623 return *desc; | 623 return *desc; |
624 } | 624 } |
625 | 625 |
626 | 626 |
627 static Object* Runtime_IsExtensible(Arguments args) { | 627 static Object* Runtime_IsExtensible(Arguments args) { |
628 ASSERT(args.length() == 1); | 628 ASSERT(args.length() == 1); |
629 CONVERT_CHECKED(JSObject, obj, args[0]); | 629 CONVERT_CHECKED(JSObject, obj, args[0]); |
630 return obj->map()->is_extensible() ? Heap::true_value() | 630 return obj->map()->is_extensible() ? Heap::true_value() |
631 : Heap::false_value(); | 631 : Heap::false_value(); |
632 } | 632 } |
(...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2881 Handle<Object> result = GetCharAt(str, index); | 2881 Handle<Object> result = GetCharAt(str, index); |
2882 return *result; | 2882 return *result; |
2883 } | 2883 } |
2884 | 2884 |
2885 // Fall back to GetObjectProperty. | 2885 // Fall back to GetObjectProperty. |
2886 return Runtime::GetObjectProperty(args.at<Object>(0), | 2886 return Runtime::GetObjectProperty(args.at<Object>(0), |
2887 args.at<Object>(1)); | 2887 args.at<Object>(1)); |
2888 } | 2888 } |
2889 | 2889 |
2890 | 2890 |
| 2891 static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { |
| 2892 ASSERT(args.length() == 5); |
| 2893 HandleScope scope; |
| 2894 Handle<JSObject> obj = args.at<JSObject>(0); |
| 2895 CONVERT_CHECKED(String, name, args[1]); |
| 2896 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
| 2897 CONVERT_CHECKED(JSFunction, fun, args[3]); |
| 2898 CONVERT_CHECKED(Smi, flag_attr, args[4]); |
| 2899 int unchecked = flag_attr->value(); |
| 2900 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 2901 |
| 2902 LookupResult result; |
| 2903 obj->LocalLookupRealNamedProperty(name, &result); |
| 2904 |
| 2905 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 2906 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION |
| 2907 // delete it to avoid running into trouble in DefineAccessor, which |
| 2908 // handles this incorrectly if the property is readonly (does nothing) |
| 2909 if (result.type() == FIELD || result.type() == NORMAL |
| 2910 || result.type() == CONSTANT_FUNCTION) |
| 2911 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); |
| 2912 |
| 2913 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); |
| 2914 } |
| 2915 |
| 2916 static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) { |
| 2917 ASSERT(args.length() == 4); |
| 2918 HandleScope scope; |
| 2919 Handle<Object> obj = args.at<Object>(0); |
| 2920 Handle<Object> name = args.at<Object>(1); |
| 2921 Handle<Object> obj_value = args.at<Object>(2); |
| 2922 Handle<JSObject> js_object = Handle<JSObject>::cast(obj); |
| 2923 Handle<String> key_string = Handle<String>::cast(name); |
| 2924 |
| 2925 CONVERT_CHECKED(Smi, flag, args[3]); |
| 2926 int unchecked = flag->value(); |
| 2927 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 2928 |
| 2929 LookupResult result; |
| 2930 js_object->LocalLookupRealNamedProperty(*key_string, &result); |
| 2931 |
| 2932 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 2933 |
| 2934 // Take special care when attributes are different and there is already |
| 2935 // a property. For simplicity we normalize the property which enables us |
| 2936 // to not worry about changing the instance_descriptor and creating a new |
| 2937 // map. The current version of SetObjectProperty does not handle attributes |
| 2938 // correctly in the case where a property is a field and is reset with |
| 2939 // new attributes. |
| 2940 if (result.IsProperty() && attr != result.GetAttributes()) { |
| 2941 PropertyDetails details = PropertyDetails(attr, NORMAL); |
| 2942 // New attributes - normalize to avoid writing to instance descriptor |
| 2943 js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0); |
| 2944 return js_object->SetNormalizedProperty(*key_string, *obj_value, details); |
| 2945 } |
| 2946 |
| 2947 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); |
| 2948 } |
| 2949 |
| 2950 |
2891 Object* Runtime::SetObjectProperty(Handle<Object> object, | 2951 Object* Runtime::SetObjectProperty(Handle<Object> object, |
2892 Handle<Object> key, | 2952 Handle<Object> key, |
2893 Handle<Object> value, | 2953 Handle<Object> value, |
2894 PropertyAttributes attr) { | 2954 PropertyAttributes attr) { |
2895 HandleScope scope; | 2955 HandleScope scope; |
2896 | 2956 |
2897 if (object->IsUndefined() || object->IsNull()) { | 2957 if (object->IsUndefined() || object->IsNull()) { |
2898 Handle<Object> args[2] = { key, object }; | 2958 Handle<Object> args[2] = { key, object }; |
2899 Handle<Object> error = | 2959 Handle<Object> error = |
2900 Factory::NewTypeError("non_object_property_store", | 2960 Factory::NewTypeError("non_object_property_store", |
(...skipping 5281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8182 } else { | 8242 } else { |
8183 // Handle last resort GC and make sure to allow future allocations | 8243 // Handle last resort GC and make sure to allow future allocations |
8184 // to grow the heap without causing GCs (if possible). | 8244 // to grow the heap without causing GCs (if possible). |
8185 Counters::gc_last_resort_from_js.Increment(); | 8245 Counters::gc_last_resort_from_js.Increment(); |
8186 Heap::CollectAllGarbage(false); | 8246 Heap::CollectAllGarbage(false); |
8187 } | 8247 } |
8188 } | 8248 } |
8189 | 8249 |
8190 | 8250 |
8191 } } // namespace v8::internal | 8251 } } // namespace v8::internal |
OLD | NEW |